From 21432c8de0d8a1c6c952e81ce6287a76989aa02e Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Mon, 6 Jun 2022 11:11:29 +0200 Subject: [PATCH 01/19] Always check assertions The builtin `assert` of Java is disabled by default (at least in release mode), but this is a research project so logical consistency is really important and the performance implications are not as problematic. --- .../variantsync/diffdetective/diff/difftree/DiffNode.java | 4 ++-- .../difftree/transform/CollapseNestedNonEditedMacros.java | 7 ++++--- .../variantsync/diffdetective/internal/SimpleRenderer.java | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java index f785f4085..2a4eb8c3e 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java @@ -363,12 +363,12 @@ public void drop() { } private void dropBeforeChild(final DiffNode child) { - assert child.beforeParent == this; + Assert.assertTrue(child.beforeParent == this); child.beforeParent = null; } private void dropAfterChild(final DiffNode child) { - assert child.afterParent == this; + Assert.assertTrue(child.afterParent == this); child.afterParent = null; } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java index afd404fa4..adc367e69 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java @@ -7,6 +7,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffType; import org.variantsync.diffdetective.diff.difftree.traverse.DiffTreeTraversal; +import org.variantsync.diffdetective.util.Assert; import java.util.ArrayList; import java.util.List; @@ -45,7 +46,7 @@ public void transform(final DiffTree diffTree) { // All found chains should at least have size 2. for (final Stack chain : chains) { - assert chain.size() >= 2; + Assert.assertTrue(chain.size() >= 2); } // System.out.println(StringUtils.prettyPrintNestedCollections(chains)); @@ -97,7 +98,7 @@ private static void collapseChain(Stack chain) { final ArrayList featureMappings = new ArrayList<>(chain.size()); DiffNode lastPopped = null; - assert !chain.isEmpty(); + Assert.assertTrue(!chain.isEmpty()); while (!chain.isEmpty()) { lastPopped = chain.pop(); @@ -118,7 +119,7 @@ private static void collapseChain(Stack chain) { } } - assert head == lastPopped; + Assert.assertTrue(head == lastPopped); final DiffNode beforeParent = head.getBeforeParent(); final DiffNode afterParent = head.getAfterParent(); diff --git a/src/main/java/org/variantsync/diffdetective/internal/SimpleRenderer.java b/src/main/java/org/variantsync/diffdetective/internal/SimpleRenderer.java index 69de94765..766752706 100644 --- a/src/main/java/org/variantsync/diffdetective/internal/SimpleRenderer.java +++ b/src/main/java/org/variantsync/diffdetective/internal/SimpleRenderer.java @@ -14,6 +14,7 @@ import org.variantsync.diffdetective.mining.DiffTreeMiner; import org.variantsync.diffdetective.mining.RWCompositePatternNodeFormat; import org.variantsync.diffdetective.mining.RWCompositePatternTreeFormat; +import org.variantsync.diffdetective.util.Assert; import org.variantsync.diffdetective.util.FileUtils; import java.io.IOException; @@ -156,7 +157,7 @@ public static void main(String[] args) throws IOException { final List transform = DiffTreeMiner.Postprocessing(repository); final PatchDiff patch = DiffTreeParser.parsePatch(repository, file, commit); - assert patch != null; + Assert.assertNotNull(patch != null); DiffTreeTransformer.apply(transform, patch.getDiffTree()); renderer.render(patch, Path.of("render", repoName), RENDER_OPTIONS_TO_USE); } From 123c479b124c0de4ada1b22cba9be86451a15873 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sat, 3 Sep 2022 16:25:30 +0200 Subject: [PATCH 02/19] Use Set instead of Map<*, Boolean> in DiffTreeTraversal --- .../diff/difftree/traverse/DiffTreeTraversal.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java index 671630afe..7c81ce6c0 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java @@ -3,7 +3,8 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import java.util.function.Consumer; /** @@ -21,12 +22,12 @@ * @author Paul Bittner */ public class DiffTreeTraversal { - private final HashMap visited; + private final Set visited; private final DiffTreeVisitor visitor; private DiffTreeTraversal(final DiffTreeVisitor visitor) { this.visitor = visitor; - this.visited = new HashMap<>(); + this.visited = new HashSet<>(); } /** @@ -85,11 +86,6 @@ public void visitChildrenOf(final DiffNode subtree) { * False if the node was already marked visited. */ public boolean markAsVisited(final DiffNode node) { - final Integer id = node.getID(); - if (!visited.containsKey(id)) { - visited.put(id, true); - return true; - } - return false; + return visited.add(node.getID()); } } From a15db205c0748adcc88ab29b13310139106eeb66 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sat, 3 Sep 2022 16:26:11 +0200 Subject: [PATCH 03/19] Hide an internal function of DiffTreeTraversal --- .../diffdetective/diff/difftree/traverse/DiffTreeTraversal.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java index 7c81ce6c0..03970d240 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/traverse/DiffTreeTraversal.java @@ -85,7 +85,7 @@ public void visitChildrenOf(final DiffNode subtree) { * @return True if the node was unvisited and is now marked visited. * False if the node was already marked visited. */ - public boolean markAsVisited(final DiffNode node) { + private boolean markAsVisited(final DiffNode node) { return visited.add(node.getID()); } } From 118e65b631597b23a8edb64563fa808fa63f0095 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sat, 3 Sep 2022 16:32:01 +0200 Subject: [PATCH 04/19] Point a javadoc reference to the correct overload --- .../diff/difftree/serialize/LineGraphExport.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index 5c1fad370..50525256b 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -73,8 +73,8 @@ public static Pair toLineGraphFormat(final Iterable Date: Tue, 13 Sep 2022 09:52:43 +0200 Subject: [PATCH 05/19] Install Graphviz on the CI job --- .github/workflows/maven.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 79c50e4e7..99dddc27e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -15,6 +15,8 @@ jobs: runs-on: ubuntu-latest steps: + - name: Install Graphviz + run: sudo apt-get install -y graphviz - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 From 4dd2ecdd5fc656a6432375b2520e091c2591492d Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Tue, 13 Sep 2022 12:41:46 +0200 Subject: [PATCH 06/19] Also run the CI job on the develop branch --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 99dddc27e..3b08fee2c 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -5,9 +5,9 @@ name: Java CI with Maven on: push: - branches: [ "main" ] + branches: [ "main", "develop" ] pull_request: - branches: [ "main" ] + branches: [ "main", "develop" ] jobs: build: From 285df86f3d8acd154d6f43583c33531b9e6052e7 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Tue, 6 Sep 2022 15:23:03 +0200 Subject: [PATCH 07/19] Create a TikZ exporter The layout is computed using Graphviz. --- .../diffdetective/diff/difftree/DiffNode.java | 7 + .../diff/difftree/serialize/Exporter.java | 27 ++++ .../diff/difftree/serialize/Format.java | 77 +++++++++ .../difftree/serialize/GraphvizExporter.java | 151 ++++++++++++++++++ .../diff/difftree/serialize/StyledEdge.java | 18 +++ .../diff/difftree/serialize/TikzExporter.java | 149 +++++++++++++++++ .../edgeformat/DefaultEdgeLabelFormat.java | 6 + .../serialize/edgeformat/EdgeLabelFormat.java | 25 ++- .../nodeformat/DiffNodeLabelFormat.java | 31 +++- .../nodeformat/LineNumberFormat.java | 13 ++ .../formats/DirectedEdgeLabelFormat.java | 11 ++ .../variantsync/diffdetective/util/LaTeX.java | 23 +++ src/main/resources/tikz_footer.tex | 1 + src/main/resources/tikz_header.tex | 60 +++++++ src/test/java/ExportTest.java | 52 ++++++ src/test/resources/serialize/expected.tex | 40 +++++ src/test/resources/serialize/testcase.lg | 15 ++ 17 files changed, 697 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Exporter.java create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/GraphvizExporter.java create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/StyledEdge.java create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java create mode 100644 src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/LineNumberFormat.java create mode 100644 src/main/resources/tikz_footer.tex create mode 100644 src/main/resources/tikz_header.tex create mode 100644 src/test/java/ExportTest.java create mode 100644 src/test/resources/serialize/expected.tex create mode 100644 src/test/resources/serialize/testcase.lg diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java index 2a4eb8c3e..b0f764a7f 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java @@ -919,6 +919,13 @@ public boolean isAdd() { return this.diffType.equals(DiffType.ADD); } + /** + * Returns the diff type of this node. + */ + public DiffType getDiffType() { + return this.diffType; + } + /** * Returns true if this node represents an ELIF macro. * @see CodeType#ELIF diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Exporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Exporter.java new file mode 100644 index 000000000..668c8ccac --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Exporter.java @@ -0,0 +1,27 @@ +package org.variantsync.diffdetective.diff.difftree.serialize; + +import java.io.IOException; +import java.io.OutputStream; +import org.variantsync.diffdetective.diff.difftree.DiffTree; + +/** + * Common interface for serialisation of a single {@code DiffTree}. + * Not all formats have to provide a way to deserialize a {@link DiffTree} from this format. + * + * @author Benjamin Moosherr + */ +public interface Exporter { + /** + * Export a {@code diffTree} into {@code destination}. + * + * This method should have no side effects besides writing to {@code destination}. Above all, + * {@code diffTree} shouldn't be modified. Furthermore, {@code destination} shouldn't be + * closed to allow the embedding of the exported format into a surrounding file. + * + * It can be assumed, that {@code destination} is sufficiently buffered. + * + * @param diffTree to be exported + * @param destination where the result should be written + */ + void exportDiffTree(DiffTree diffTree, OutputStream destination) throws IOException; +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java new file mode 100644 index 000000000..0a2f55a27 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java @@ -0,0 +1,77 @@ +package org.variantsync.diffdetective.diff.difftree.serialize; + +import java.util.function.Consumer; +import org.variantsync.diffdetective.diff.difftree.DiffNode; +import org.variantsync.diffdetective.diff.difftree.DiffTree; +import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; +import org.variantsync.diffdetective.diff.difftree.serialize.nodeformat.DiffNodeLabelFormat; + +/** + * Format used for exporting a {@link DiffTree}. + * For easy reusability this class is composed of separate node and edge formats. + * + * The exported {@link DiffTree} can be influenced in the following ways: + * - Providing both a node and an edge label format. + * - Changing the order, filtering or adding the nodes and edges by creating a subclass of {@code + * Format}. + */ +public class Format { + private final DiffNodeLabelFormat nodeFormat; + private final EdgeLabelFormat edgeFormat; + + public Format(DiffNodeLabelFormat nodeFormat, EdgeLabelFormat edgeFormat) { + this.nodeFormat = nodeFormat; + this.edgeFormat = edgeFormat; + } + + public DiffNodeLabelFormat getNodeFormat() { + return nodeFormat; + } + + public EdgeLabelFormat getEdgeFormat() { + return edgeFormat; + } + + /** + * Iterates over all {@link DiffNode}s in {@code diffTree} and calls {@code callback}. + * + * Exporters should use this method to enable subclasses of {@code Format} to filter nodes, add + * new nodes and change the order of the exported nodes. + * + * This implementation is equivalent to {@link DiffTree#forAll}. + * + * @param diffTree to be exported + * @param callback is called for each node + */ + public void forEachNode(DiffTree diffTree, Consumer callback) { + diffTree.forAll(callback); + } + + /** + * Iterates over all edges in {@code diffTree} and calls {@code callback}. + * + * Exporters should use this method to enable subclasses of {@code Format} to filter edges, add + * new edges and change the order of the exported edges. + * + * @param diffTree to be exported + * @param callback is called for each edge + */ + public void forEachEdge(DiffTree diffTree, Consumer callback) { + diffTree.forAll((node) -> { + processEdge(node, node.getBeforeParent(), StyledEdge.BEFORE, callback); + processEdge(node, node.getAfterParent(), StyledEdge.AFTER, callback); + }); + } + + private void processEdge(DiffNode node, DiffNode parent, StyledEdge.Style style, Consumer callback) { + if (parent == null) { + return; + } + + var edge = edgeFormat.getEdgeDirection().sort(node, parent); + callback.accept(new StyledEdge( + edge.first(), + edge.second(), + style)); + } +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/GraphvizExporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/GraphvizExporter.java new file mode 100644 index 000000000..03ecd733e --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/GraphvizExporter.java @@ -0,0 +1,151 @@ +package org.variantsync.diffdetective.diff.difftree.serialize; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.variantsync.diffdetective.diff.difftree.DiffTree; + +/** + * Exporter for the Graphviz dot format. + * Using this exporter the Graphviz application can be used to layout a {@link DiffTree} for + * visualisation. + * + * Currently only basic layout relevant information is exported, so if the result is rendered directly by Graphviz no styling is applied. + */ +public class GraphvizExporter implements Exporter { + private static final Pattern quotePattern = Pattern.compile("[\"\\\\]"); + private Format format; + + public enum LayoutAlgorithm { + DOT("dot"), + NEATO("neato"), + TWOPI("twopi"), + CIRCO("circo"), + FDP("fdp"), + SFDP("sfdp"), + PATCHWORK("patchwork"), + OSAGE("osage"); + + private final String executableName; + + private LayoutAlgorithm(String executableName) { + this.executableName = executableName; + } + + public String getExecutableName() { + return executableName; + } + } + + public enum OutputFormat { + // Graphviz supports way more output formats. Add them when necessary. + JPG("jpg"), + JSON("json"), + PDF("pdf"), + PLAIN("plain"), + PLAIN_EXT("plain-ext"), + PNG("png"), + SVG("svg"); + + private final String formatName; + + private OutputFormat(String formatName) { + this.formatName = formatName; + } + + public String getFormatName() { + return formatName; + } + } + + public GraphvizExporter(Format format) { + this.format = format; + } + + /** + * Export {@code diffTree} as Graphviz graph into {@code destination}. + * The exported graph is unstyled, but includes all necessary layout information. + * + * @param diffTree to be exported + * @param destination where the result should be written + */ + @Override + public void exportDiffTree(DiffTree diffTree, OutputStream destination) throws IOException { + var output = new PrintStream(destination); + + output.println("digraph g {"); + + format.forEachNode(diffTree, (node) -> { + output.format(" %d [label=\"%s\"];%n", + node.getID(), + escape(format.getNodeFormat().toMultilineLabel(node))); + }); + + format.forEachEdge(diffTree, (edge) -> { + output.format(" %d -> %d;%n", edge.from().getID(), edge.to().getID()); + }); + + output.println("}"); + output.flush(); + } + + /** + * Runs the Graphviz {@code dot} program returning its result. + * + * @param diffTree is the tree to be layouted by Graphviz. + * @param outputFormat is the requested format which is passed to the {@code dot} program with + * the {@code -T} flag. + * @return a buffered {@code InputStream} of the Graphviz output + */ + public InputStream computeGraphvizLayout( + DiffTree diffTree, + LayoutAlgorithm algorithm, + OutputFormat outputFormat) + throws IOException { + // Print error messages to stderr so grogramming errors in {@code exportDiffTree} can be + // diagnosed more easily. + var graphvizProcess = + new ProcessBuilder(algorithm.getExecutableName(), "-T" + outputFormat.getFormatName()) + .redirectInput(ProcessBuilder.Redirect.PIPE) + .redirectOutput(ProcessBuilder.Redirect.PIPE) + .redirectError(ProcessBuilder.Redirect.INHERIT) + .start(); + + // This could lead to a dead lock if {@code graphvizProcess} is not consuming its input and + // the OS buffer fills up, but Graphviz needs the whole graph to generate a layout so this + // should be safe. + var graphizInput = new BufferedOutputStream(graphvizProcess.getOutputStream()); + exportDiffTree(diffTree, graphizInput); + graphizInput.close(); + + return new BufferedInputStream(graphvizProcess.getInputStream()); + } + + /** + * Replaces all special characters with uninterpreted escape codes. + * + * The Graphviz parser for strings interprets some characters specially. The result of this + * function can be used in Graphviz strings (surrounded by double quotes) resulting in all + * characters appearing literally in the output. + * + * Note that some backends of Graphviz may still interpret some strings specially, most + * commonly strings containing HTML tags. + * + * @param label a list of lines to be used as verbatim label + * @return a single string which produces the lines of {@code label} verbatim + */ + static private String escape(List label) { + return label + .stream() + .map((line) -> quotePattern.matcher(line).replaceAll((match) -> "\\\\" + match.group())) + .collect(Collectors.joining("\\n")); + + } +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/StyledEdge.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/StyledEdge.java new file mode 100644 index 000000000..8251b6e1e --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/StyledEdge.java @@ -0,0 +1,18 @@ +package org.variantsync.diffdetective.diff.difftree.serialize; + +import org.variantsync.diffdetective.diff.difftree.DiffNode; + +/** + * Product of all data relevant for exporting a single edge. + * + * Note that an edge doesn't need to describe a parent child relationship between {@code from} and + * {@code to}. Information related to the type of the relation between {@code from} and {@code to} + * should be encoded into {@code style}. + */ +public record StyledEdge(DiffNode from, DiffNode to, Style style) { + public record Style(char lineGraphType, String tikzStyle) { + } + + public static final Style BEFORE = new Style('b', "before"); + public static final Style AFTER = new Style('a', "after"); +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java new file mode 100644 index 000000000..54cb293e0 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java @@ -0,0 +1,149 @@ +package org.variantsync.diffdetective.diff.difftree.serialize; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Locale; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.variantsync.diffdetective.diff.difftree.DiffTree; +import org.variantsync.diffdetective.util.LaTeX; + +/** + * Exporter for TikZ pictures which can be embedded into a LaTeX document. + * + * The resulting graph is styled using TikZ styles which have to be set using {@code \tikzset}. An + * example for all required styles can be found in the file {@code tikz_header.tex} in the resource + * directory. This particular style is used by {@link exportFullLatexExample}. + */ +public final class TikzExporter implements Exporter { + private static final Pattern graphvizNodePattern = Pattern.compile("^node (\\w+) ([0-9.]+) ([0-9.]+) .*$"); + private Format format; + + public TikzExporter(Format format) { + this.format = format; + } + + /** + * Export {@code diffTree} as TikZ graph into {@code destination}. + * + * The exported graph starts and ends with the {@code tikzpicture} environment and does not + * include surrounding LaTeX code like the preamble. For a quick way to set up a working LaTeX + * document see {@link exportFullLatexExample}. + * + * @param diffTree to be exported + * @param destination where the result should be written + */ + @Override + public void exportDiffTree(DiffTree diffTree, OutputStream destination) throws IOException { + exportDiffTree(diffTree, GraphvizExporter.LayoutAlgorithm.DOT, destination); + } + + /** + * Export {@code diffTree} as TikZ graph into {@code destination}. + * + * Same as {@link exportDiffTree(DiffTree, OutputStream)}, but allows the selection of + * a different Graphviz layout algorithm. + */ + public void exportDiffTree( + DiffTree diffTree, + GraphvizExporter.LayoutAlgorithm algorithm, + OutputStream destination + ) throws IOException { + // Start tikz picture. + var output = new PrintStream(destination); + output.println("\\begin{tikzpicture}"); + + // Convert the layout information received by Graphviz to coordinates used by TikZ. + try ( + var graphvizExporter = new GraphvizExporter(format) + .computeGraphvizLayout( + diffTree, + algorithm, + GraphvizExporter.OutputFormat.PLAIN); + var unbufferedGraphvizOutput = new InputStreamReader(graphvizExporter); + var graphizOutput = new BufferedReader(unbufferedGraphvizOutput + )) { + // Skip scale and dimensions + graphizOutput.readLine(); + + String line; + while ((line = graphizOutput.readLine()) != null) { + var nodeMatcher = graphvizNodePattern.matcher(line); + if (nodeMatcher.matches()) { + var id = nodeMatcher.group(1); + var x = nodeMatcher.group(2); + var y = nodeMatcher.group(3); + + output.format("\t\\coordinate (%s) at (%s,%s);%n", id, x, y); + } + } + } + + // Add all TikZ nodes positioned at the Graphviz coordinates. + format.forEachNode(diffTree, (node) -> { + String escapedLabel = + format + .getNodeFormat() + .toMultilineLabel(node) + .stream() + .map(LaTeX::escape) + .collect(Collectors + .joining(" \\\\ ")); + + output.format("%n\t\\node[%s, %s] (node_%s) at (%s) {};%n", + node.isCode() ? "artefact" : "annotation", + node.getDiffType().toString().toLowerCase(Locale.ROOT), + node.getID(), + node.getID()); + output.format("\t\\node[textbox] at (%s) {%s};%n", + node.getID(), + escapedLabel); + }); + + // Add all TikZ edges positioned. + output.format("%n\t\\draw[vtdarrow]"); + format.forEachEdge(diffTree, (edge) -> { + output.format("%n\t\t(node_%d) edge[%s] (node_%d)", + edge.from().getID(), + edge.style().tikzStyle(), + edge.to().getID()); + }); + output.println(";"); + + // Finish the TikZ picture. + output.println("\\end{tikzpicture}"); + output.flush(); + } + + /** + * Exports a ready to compile LaTeX document containing a TikZ graph exported by {@link + * exportDiffTree}. + * + * The resulting document should be used as prototype not as ready to be published + * visualisation. To discourage further processing the API differs from {@code exportDiffTree} + * by exporting directly into a file. + * + * @param diffTree to be exported + * @param filename of the destination file + */ + public void exportFullLatexExample(DiffTree diffTree, String filename) throws IOException { + try (var file = new BufferedOutputStream(new FileOutputStream(filename))) { + try (var header = new BufferedInputStream(getClass().getResourceAsStream("/tikz_header.tex"))) { + header.transferTo(file); + } + + exportDiffTree(diffTree, file); + + try (var footer = new BufferedInputStream(getClass().getResourceAsStream("/tikz_footer.tex"))) { + footer.transferTo(file); + } + } + } +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java index f862749f4..213c81615 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java @@ -2,6 +2,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; +import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; import org.variantsync.functjonal.Functjonal; /** @@ -29,4 +30,9 @@ public DefaultEdgeLabelFormat(final EdgeLabelFormat.Direction direction) { public String edgeToLineGraph(DiffNode from, DiffNode to, String labelPrefix) { return Functjonal.unwords(LineGraphConstants.LG_EDGE, from.getID(), to.getID(), labelPrefix); } + + @Override + public String labelOf(StyledEdge edge) { + return ""; + } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java index 35d71e690..daef7e02c 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java @@ -2,11 +2,13 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; +import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; import org.variantsync.diffdetective.diff.difftree.serialize.LinegraphFormat; import org.variantsync.diffdetective.util.Assert; import org.variantsync.diffdetective.util.StringUtils; import org.variantsync.functjonal.Pair; +import java.util.List; import java.util.Map; /** @@ -55,7 +57,7 @@ public enum Direction { * @return Both values sorted according to this direction. * @param Value type. */ - Pair sort(A child, A parent) { + public Pair sort(A child, A parent) { if (this == ChildToParent) { return new Pair<>(child, parent); } else { @@ -188,4 +190,25 @@ private String edgeToLineGraphSorted(DiffNode desiredFrom, DiffNode desiredTo, f * @return A line for a linegraph file that describes the given edge. */ protected abstract String edgeToLineGraph(DiffNode from, DiffNode to, final String labelPrefix); + + /** + * Converts a {@link StyledEdge} into a label suitable for exporting. + * This may be human readable text or machine parseable metadata. + * + * @param edge The {@link StyledEdge} to be labeled + * @return a label for {@code edge} + */ + public abstract String labelOf(StyledEdge edge); + + /** + * Converts a {@link StyledEdge} into a multi line label suitable for exporting. + * This should be human readable text. Use a single line for machine parseable metadata + * ({@link labelOf}). + * + * @param edge The {@link StyledEdge} to be labeled + * @return a list of lines of the label for {@code edge} + */ + public List multilineLabelOf(StyledEdge edge) { + return List.of(labelOf(edge)); + } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java index cab65764a..795a90f0c 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java @@ -1,5 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.serialize.nodeformat; +import java.util.List; + import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTreeSource; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; @@ -21,14 +23,27 @@ public interface DiffNodeLabelFormat extends LinegraphFormat { default DiffNode fromLabelAndId(final String lineGraphNodeLabel, final int nodeId) { return DiffNode.fromID(nodeId, lineGraphNodeLabel); } - - /** - * Converts a {@link DiffNode} into a {@link DiffNode} label of line graph. - * - * @param node The {@link DiffNode} to be converted - * @return The corresponding line graph line - */ - String toLabel(final DiffNode node); + + /** + * Converts a {@link DiffNode} into a label suitable for exporting. + * This may be human readable text or machine parseable metadata. + * + * @param node The {@link DiffNode} to be labeled + * @return a label for {@code node} + */ + String toLabel(DiffNode node); + + /** + * Converts a {@link DiffNode} into a multi line label suitable for exporting. + * This should be human readable text. Use a single line for machine parseable metadata + * ({@link toLabel}). + * + * @param node The {@link DiffNode} to be labeled + * @return a list of lines of the label for {@code node} + */ + default List toMultilineLabel(DiffNode node) { + return List.of(toLabel(node)); + } /** * Converts a line describing a graph (starting with "t # ") in line graph format into a {@link DiffTreeSource}. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/LineNumberFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/LineNumberFormat.java new file mode 100644 index 000000000..f69618e7a --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/LineNumberFormat.java @@ -0,0 +1,13 @@ +package org.variantsync.diffdetective.diff.difftree.serialize.nodeformat; + +import org.variantsync.diffdetective.diff.difftree.DiffNode; + +/** + * Labels nodes using their line number in the source diff. + */ +public class LineNumberFormat implements DiffNodeLabelFormat { + @Override + public String toLabel(final DiffNode node) { + return String.valueOf(node.getFromLine().inDiff); + } +} diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java index 2aebb8f67..1d37e9d37 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java @@ -2,6 +2,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; +import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; import org.variantsync.functjonal.Functjonal; @@ -65,6 +66,16 @@ protected String edgeToLineGraph(DiffNode from, DiffNode to, final String label) ); } + @Override + public String labelOf(StyledEdge edge) { + return Functjonal.intercalate( + LABEL_SEPARATOR, + "", + nodeFormatter.toLabel(edge.from()), + nodeFormatter.toLabel(edge.to()) + ); + } + @Override public String getName() { return this.getClass().getName() + " with " + nodeFormatter.getName(); diff --git a/src/main/java/org/variantsync/diffdetective/util/LaTeX.java b/src/main/java/org/variantsync/diffdetective/util/LaTeX.java index 342b1df86..e39cc7999 100644 --- a/src/main/java/org/variantsync/diffdetective/util/LaTeX.java +++ b/src/main/java/org/variantsync/diffdetective/util/LaTeX.java @@ -6,4 +6,27 @@ public final class LaTeX { public static final String TABLE_SEPARATOR = " & "; /** Delimiter between LaTex table rows. */ public static final String TABLE_ENDROW = "\\\\" + StringUtils.LINEBREAK; + + /** + * Characters suitable for use with the {@code \verb} command. In decreasing preference. + */ + private static final char[] verbDelimiters = "|/!?+\"'-_=~#@$&^:;.,".toCharArray(); + + /** + * Wraps {@code text} into a {@code \verb} command. + * Automatically tries to select a suitable delimiter not contained in {@code text}. + * + * @param text a string which should appear verbatim in LaTeX output + * @return LaTeX source code producing {@code text} verbatim + * @throws IllegalArgumentException if no suitable delimiter could be found. + */ + public static String escape(String text) { + for (char verbChar : verbDelimiters) { + if (!text.contains(String.valueOf(verbChar))) { + return "\\verb" + verbChar + text + verbChar; + } + } + + throw new IllegalArgumentException("No suitable LaTeX escape character found for the string: " + text); + } } diff --git a/src/main/resources/tikz_footer.tex b/src/main/resources/tikz_footer.tex new file mode 100644 index 000000000..6b47932f5 --- /dev/null +++ b/src/main/resources/tikz_footer.tex @@ -0,0 +1 @@ +\end{document} diff --git a/src/main/resources/tikz_header.tex b/src/main/resources/tikz_header.tex new file mode 100644 index 000000000..9cbe189d5 --- /dev/null +++ b/src/main/resources/tikz_header.tex @@ -0,0 +1,60 @@ +\documentclass[tikz]{standalone} + +\usepackage{xcolor} +\usepackage{tikz} +\usetikzlibrary{positioning} +\usetikzlibrary{shapes.symbols} +\usetikzlibrary{arrows.meta} + +%%% COLORS FOR DIFF SNIPPETS AND DIFFTREE NODES +\definecolor{darkpastelgreen}{rgb}{0.01, 0.75, 0.24} +\definecolor{darkpastelblue}{rgb}{0.47, 0.62, 0.8} +\definecolor{pastelorange}{rgb}{1.0, 0.7, 0.28} + +\definecolor{diffAddColour}{RGB}{161,215,106} +\definecolor{diffRemColour}{RGB}{233,163,201} + +\colorlet{diffAddColourDarkened}{darkpastelgreen!50!darkpastelblue} +\colorlet{diffAddColour}{diffAddColourDarkened!80} +\colorlet{diffRemColourDarkened}{pastelorange} +\colorlet{diffRemColour}{diffRemColourDarkened!80} + +%%% COLORS FOR SYMBOLS (+, -, ., b, a) +\newcommand{\epAddColor}{diffAddColourDarkened} +\newcommand{\epRemColor}{diffRemColourDarkened} +\newcommand{\epNonColor}{gray} + +%%% COLORS FOR DIFFTREES +\newcommand{\vtdEdgeBeforeColor}{diffRemColourDarkened} +\newcommand{\vtdEdgeAfterColor}{diffAddColourDarkened} + +\definecolor{vtdAnnotationBorderColor}{rgb}{0.2, 0.4, 0.9} +\definecolor{vtdCodeColor}{rgb}{0,0,0} + +%%% tikz stuff + +%% Load the library +%\usetikzlibrary{external} +%% Enable the library !!!>>> MUST be in the preamble << Date: Tue, 13 Sep 2022 09:26:57 +0200 Subject: [PATCH 08/19] Adapt the line graph exporter to the new `Exporter` interface Line graph specific export code is moved to the line graph exporter. This changes the line endings to use the OS dependent representation through the use of `PrintStream`. Currently there is an unnecessary conversion from `String` to `ByteArray` and back because `OutputStream`s are used. This will be optimised in the future by directly outputting to the desired devices (file and terminal) without converting back to a `String` representation. --- .../serialize/DiffTreeLineGraphExporter.java | 84 +++++++++---------- .../diff/difftree/serialize/Format.java | 84 ++++++++++++++++--- .../difftree/serialize/LineGraphExport.java | 9 +- .../edgeformat/DefaultEdgeLabelFormat.java | 7 -- .../serialize/edgeformat/EdgeLabelFormat.java | 50 ----------- .../nodeformat/DiffNodeLabelFormat.java | 12 +-- .../formats/DirectedEdgeLabelFormat.java | 15 ---- 7 files changed, 120 insertions(+), 141 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java index 5a737ec0b..411659a9f 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/DiffTreeLineGraphExporter.java @@ -1,64 +1,60 @@ package org.variantsync.diffdetective.diff.difftree.serialize; -import org.variantsync.diffdetective.diff.difftree.DiffNode; +import java.io.OutputStream; +import java.io.PrintStream; + import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.util.StringUtils; +import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; +import org.variantsync.functjonal.Functjonal; /** * Exporter that converts a single DiffTree's nodes and edges to linegraph. */ -public class DiffTreeLineGraphExporter { - private final StringBuilder nodesString = new StringBuilder(); - private final StringBuilder edgesString = new StringBuilder(); - - private final DiffTree diffTree; - +public class DiffTreeLineGraphExporter implements Exporter { + private final Format format; private final DiffTreeSerializeDebugData debugData; - /** - * Creates a new exporter that will export the given tree. - */ - public DiffTreeLineGraphExporter(DiffTree treeToExport) { - this.diffTree = treeToExport; + public DiffTreeLineGraphExporter(Format format) { + this.format = format; this.debugData = new DiffTreeSerializeDebugData(); } + public DiffTreeLineGraphExporter(DiffTreeLineGraphExportOptions options) { + this(new Format(options.nodeFormat(), options.edgeFormat())); + } + /** - * Converts the given node and its edges to linegraph using the formats specified in the given options. - * The produced linegraph statements will be added to the internal StringBuilders. - * @param node The node to convert to linegraph format together with its edges. - * @param options Options that specify the node and edge format to use. + * Export a line graph of {@code diffTree} into {@code destination}. + * + * @param diffTree to be exported + * @param destination where the result should be written */ - private void visit(DiffNode node, DiffTreeLineGraphExportOptions options) { - switch (node.diffType) { - case ADD -> ++debugData.numExportedAddNodes; - case REM -> ++debugData.numExportedRemNodes; - case NON -> ++debugData.numExportedNonNodes; - } + @Override + public void exportDiffTree(DiffTree diffTree, OutputStream destination) { + var output = new PrintStream(destination); + format.forEachNode(diffTree, (node) -> { + switch (node.diffType) { + case ADD -> ++debugData.numExportedAddNodes; + case REM -> ++debugData.numExportedRemNodes; + case NON -> ++debugData.numExportedNonNodes; + } - nodesString - .append(options.nodeFormat().toLineGraphLine(node)) - .append(StringUtils.LINEBREAK); + output.println(LineGraphConstants.LG_NODE + " " + node.getID() + " " + format.getNodeFormat().toLabel(node)); + }); - edgesString - .append(options.edgeFormat().getParentEdgeLines(node)); - } + format.forEachUniqueEdge(diffTree, (edges) -> { + output.print(Functjonal.unwords(LineGraphConstants.LG_EDGE, edges.get(0).from().getID(), edges.get(0).to().getID(), "")); - /** - * Export this exporter's tree using the given options. - * This method will return the final linegraph as string. - * The string will contain all linegraph statements for the tree's nodes and edges, - * but not the tree header. - * @param options Options that specify the node and edge format to use. - * @return The linegraph as String. - * @see LineGraphExport#composeTreeInLineGraph - */ - public String export(DiffTreeLineGraphExportOptions options) { - diffTree.forAll(n -> visit(n, options)); - final String result = nodesString.toString() + edgesString; - StringUtils.clear(nodesString); - StringUtils.clear(edgesString); - return result; + for (var edge : edges) { + output.print(edge.style().lineGraphType()); + } + + for (var edge : edges) { + output.print(format.getEdgeFormat().labelOf(edge)); + } + + output.println(); + }); } /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java index 0a2f55a27..66b5fb156 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/Format.java @@ -1,5 +1,6 @@ package org.variantsync.diffdetective.diff.difftree.serialize; +import java.util.List; import java.util.function.Consumer; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; @@ -53,25 +54,86 @@ public void forEachNode(DiffTree diffTree, Consumer callback) { * Exporters should use this method to enable subclasses of {@code Format} to filter edges, add * new edges and change the order of the exported edges. * + * This implementation uses {@link forEachUniqueEdge} by calling {@code callback} for each edge + * in the order given by the lists of {@link forEachUniqueEdge}. + * * @param diffTree to be exported * @param callback is called for each edge */ public void forEachEdge(DiffTree diffTree, Consumer callback) { + forEachUniqueEdge(diffTree, (edges) -> { + for (var edge : edges) { + callback.accept(edge); + } + }); + } + + /** + * Iterates over all edges in {@code diffTree} and calls {@code callback}, visiting parallel edges only once. + * + * Two edges are parallel if they start at the same node and end at the same node. Note that + * the direction of directed edges matters. + * + * All parallel edges are collected into a list and are passed once to {@code callback}. + * + * Exporters should use this method to enable subclasses of {@code Format} to filter edges, add + * new edges and change the order of the exported edges. + * + * @param diffTree to be exported + * @param callback is called for each unique edge + */ + public void forEachUniqueEdge(DiffTree diffTree, Consumer> callback) { diffTree.forAll((node) -> { - processEdge(node, node.getBeforeParent(), StyledEdge.BEFORE, callback); - processEdge(node, node.getAfterParent(), StyledEdge.AFTER, callback); + var beforeParent = node.getBeforeParent(); + var afterParent = node.getAfterParent(); + + // Are both parent edges the same? + if (beforeParent != null && afterParent != null && beforeParent == afterParent) { + callback.accept(List.of(beforeEdge(node), afterEdge(node))); + } else { + if (beforeParent != null) { + callback.accept(List.of(beforeEdge(node))); + } + if (afterParent != null) { + callback.accept(List.of(afterEdge(node))); + } + } }); } - private void processEdge(DiffNode node, DiffNode parent, StyledEdge.Style style, Consumer callback) { - if (parent == null) { - return; - } + /** + * Constructs a {@link StyledEdge} from {@code node} and its before parent. + * + * The order of these nodes is permuted according to {@link EdgeLabelFormat#getEdgeDirection} + * of {@link getEdgeFormat()}. + */ + protected StyledEdge beforeEdge(DiffNode node) { + return sortedEdgeWithLabel(node, node.getBeforeParent(), StyledEdge.BEFORE); + } - var edge = edgeFormat.getEdgeDirection().sort(node, parent); - callback.accept(new StyledEdge( - edge.first(), - edge.second(), - style)); + /** + * Constructs a {@link StyledEdge} from {@code node} and its after parent. + * + * The order of these nodes is permuted according to {@link EdgeLabelFormat#getEdgeDirection} + * of {@link getEdgeFormat()}. + */ + protected StyledEdge afterEdge(DiffNode node) { + return sortedEdgeWithLabel(node, node.getAfterParent(), StyledEdge.AFTER); + } + + /** + * Constructs a {@link StyledEdge} from {@code originalFrom} to {@code originalTo}. + * + * The order of these nodes is permuted according to {@link EdgeLabelFormat#getEdgeDirection} + * of {@link getEdgeFormat()}. + * + * @param originalFrom the origin of the constructed edge + * @param originalTo the destination of the constructed edge + * @param style the export style of the constructed edge + * @return a new {@link StyledEdge} + */ + protected StyledEdge sortedEdgeWithLabel(DiffNode originalFrom, DiffNode originalTo, StyledEdge.Style style) { + var edge = edgeFormat.getEdgeDirection().sort(originalFrom, originalTo); + return new StyledEdge(edge.first(), edge.second(), style); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java index 50525256b..1abb8c01d 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphExport.java @@ -1,5 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.serialize; +import java.io.ByteArrayOutputStream; + import org.tinylog.Logger; import org.variantsync.diffdetective.analysis.AnalysisResult; import org.variantsync.diffdetective.diff.CommitDiff; @@ -29,9 +31,10 @@ public static Pair toLineGraphFormat(final D diffTree.assertConsistency(); if (options.treeFilter().test(diffTree)) { - final DiffTreeLineGraphExporter exporter = new DiffTreeLineGraphExporter(diffTree); - final String result = exporter.export(options); - return new Pair<>(exporter.getDebugData(), result); + final var exporter = new DiffTreeLineGraphExporter(options); + var output = new ByteArrayOutputStream(); + exporter.exportDiffTree(diffTree, output); + return new Pair<>(exporter.getDebugData(), output.toString()); } return null; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java index 213c81615..8b638e871 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/DefaultEdgeLabelFormat.java @@ -1,9 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.serialize.edgeformat; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; -import org.variantsync.functjonal.Functjonal; /** * Default implementation of {@link EdgeLabelFormat}. @@ -26,11 +24,6 @@ public DefaultEdgeLabelFormat(final EdgeLabelFormat.Direction direction) { super(direction); } - @Override - public String edgeToLineGraph(DiffNode from, DiffNode to, String labelPrefix) { - return Functjonal.unwords(LineGraphConstants.LG_EDGE, from.getID(), to.getID(), labelPrefix); - } - @Override public String labelOf(StyledEdge edge) { return ""; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java index daef7e02c..3ab75ce95 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/edgeformat/EdgeLabelFormat.java @@ -5,7 +5,6 @@ import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; import org.variantsync.diffdetective.diff.difftree.serialize.LinegraphFormat; import org.variantsync.diffdetective.util.Assert; -import org.variantsync.diffdetective.util.StringUtils; import org.variantsync.functjonal.Pair; import java.util.List; @@ -142,55 +141,6 @@ public void connect(final String lineGraphLine, final Map nod connectAccordingToLabel(childNode, parentNode, name); } - /** - * Serializes the edges from given node to its parent - * to a string of lines, where each edge is placed on one line. - * - * @param node The {@link DiffNode} whose edges to parents to export. - * @return Linegraph lines for each edge from the given node to its parents. All lines are put into the same string and separated by a line break ("\n"). - */ - public String getParentEdgeLines(final DiffNode node) { - final DiffNode beforeParent = node.getBeforeParent(); - final DiffNode afterParent = node.getAfterParent(); - final boolean hasBeforeParent = beforeParent != null; - final boolean hasAfterParent = afterParent != null; - - StringBuilder edgesString = new StringBuilder(); - // If the node has exactly one parent - if (hasBeforeParent && hasAfterParent && beforeParent == afterParent) { - edgesString - .append(edgeToLineGraphSorted(node, beforeParent, LineGraphConstants.BEFORE_AND_AFTER_PARENT)) - .append(StringUtils.LINEBREAK); - } else { - if (hasBeforeParent) { - edgesString - .append(edgeToLineGraphSorted(node, beforeParent, LineGraphConstants.BEFORE_PARENT)) - .append(StringUtils.LINEBREAK); - } - if (hasAfterParent) { - edgesString - .append(edgeToLineGraphSorted(node, afterParent, LineGraphConstants.AFTER_PARENT)) - .append(StringUtils.LINEBREAK); - } - } - return edgesString.toString(); - } - - private String edgeToLineGraphSorted(DiffNode desiredFrom, DiffNode desiredTo, final String labelPrefix) { - final Pair sorted = edgeDirection.sort(desiredFrom, desiredTo); - return edgeToLineGraph(sorted.first(), sorted.second(), labelPrefix); - } - - /** - * Creates a linegraph edge in the direction from -> to. - * The edge's label should be prefixed by the given prefix. - * @param from Node the edge begins at. - * @param to Node the edge ends at. - * @param labelPrefix Prefix for the produced edge's label. - * @return A line for a linegraph file that describes the given edge. - */ - protected abstract String edgeToLineGraph(DiffNode from, DiffNode to, final String labelPrefix); - /** * Converts a {@link StyledEdge} into a label suitable for exporting. * This may be human readable text or machine parseable metadata. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java index 795a90f0c..d8744decd 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelFormat.java @@ -68,14 +68,4 @@ default Pair fromLineGraphLine(final String lineGraphLine) { final String label = lineGraphLine.substring(idEnd + 1); return new Pair<>(nodeId, fromLabelAndId(label, nodeId)); } - - /** - * Serializes the given node to a line in linegraph format. - * - * @param node The {@link DiffNode} to be converted - * @return The entire line graph line of a {@link DiffNode}. - */ - default String toLineGraphLine(final DiffNode node) { - return LineGraphConstants.LG_NODE + " " + node.getID() + " " + toLabel(node); - } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java index 1d37e9d37..67a076c54 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DirectedEdgeLabelFormat.java @@ -1,7 +1,6 @@ package org.variantsync.diffdetective.mining.formats; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.diff.difftree.LineGraphConstants; import org.variantsync.diffdetective.diff.difftree.serialize.StyledEdge; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; import org.variantsync.functjonal.Functjonal; @@ -52,20 +51,6 @@ protected void connectAccordingToLabel(DiffNode child, DiffNode parent, String e super.connectAccordingToLabel(child, parent, edgeLabel); } - protected String edgeToLineGraph(DiffNode from, DiffNode to, final String label) { - return Functjonal.unwords( - LineGraphConstants.LG_EDGE, - from.getID(), - to.getID(), - Functjonal.intercalate( - LABEL_SEPARATOR, - label, - nodeFormatter.toLabel(from), - nodeFormatter.toLabel(to) - ) - ); - } - @Override public String labelOf(StyledEdge edge) { return Functjonal.intercalate( From fd3375265e204c11ab5ddda9ba63a231887ed5dc Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 12:11:57 +0200 Subject: [PATCH 09/19] Fix a documentation typo in ShellException and HistoryAnalysis --- .../org/variantsync/diffdetective/analysis/HistoryAnalysis.java | 2 +- .../org/variantsync/diffdetective/shell/ShellException.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java index 4681795b7..3d44e79c3 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/HistoryAnalysis.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; /** - * An analyses that is performed for the entire commit histories of each given git repositoy. + * An analyses that is performed for the entire commit histories of each given git repository. * @param repositoriesToAnalyze The repositories whose commit history should be analyzed. * @param outputDir The directory to which any produced results should be written. * @param commitsToProcessPerThread Number of commits that should be processed by each single thread if multithreading is used. diff --git a/src/main/java/org/variantsync/diffdetective/shell/ShellException.java b/src/main/java/org/variantsync/diffdetective/shell/ShellException.java index c88fcb1e2..f98c25115 100644 --- a/src/main/java/org/variantsync/diffdetective/shell/ShellException.java +++ b/src/main/java/org/variantsync/diffdetective/shell/ShellException.java @@ -21,7 +21,7 @@ public ShellException(Exception e) { /** * Constructs a {@code ShellException} on command failures indicated by an exit code. - * If possible both {@code stdout} and {@code stderr} should be provided in @{code output}. + * If possible both {@code stdout} and {@code stderr} should be provided in {@code output}. */ public ShellException(List output) { super(convert(output)); From 6752d12196aecc44390f1370396c6bd6660b09db Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 12:26:53 +0200 Subject: [PATCH 10/19] Rename CodeType to NodeType --- .../diffdetective/diff/difftree/DiffNode.java | 96 +++++++++---------- .../diffdetective/diff/difftree/DiffTree.java | 4 +- .../difftree/{CodeType.java => NodeType.java} | 24 ++--- .../diff/difftree/parse/DiffNodeParser.java | 10 +- .../diff/difftree/parse/DiffTreeParser.java | 2 +- .../difftree/parse/MultiLineMacroParser.java | 6 +- .../difftree/serialize/LineGraphImport.java | 4 +- .../nodeformat/DebugDiffNodeFormat.java | 6 +- .../nodeformat/DiffNodeLabelPrettyfier.java | 14 +-- .../FormulasAndLineNumbersNodeFormat.java | 4 +- .../nodeformat/MappingsDiffNodeFormat.java | 10 +- .../nodeformat/TypeDiffNodeFormat.java | 6 +- .../transform/CollapseElementaryPatterns.java | 4 +- .../CollapseNestedNonEditedMacros.java | 8 +- .../mining/RWCompositePatternNodeFormat.java | 4 +- .../formats/DebugMiningDiffNodeFormat.java | 20 ++-- .../mining/formats/MiningNodeFormat.java | 8 +- .../formats/ReleaseMiningDiffNodeFormat.java | 28 +++--- .../postprocessing/MiningPostprocessing.java | 2 +- .../pattern/elementary/ElementaryPattern.java | 2 +- .../ElementaryPatternCatalogue.java | 2 +- .../proposed/ProposedElementaryPatterns.java | 2 +- src/test/java/TestLineNumbers.java | 2 +- 23 files changed, 134 insertions(+), 134 deletions(-) rename src/main/java/org/variantsync/diffdetective/diff/difftree/{CodeType.java => NodeType.java} (76%) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java index b0f764a7f..b3df9c4b2 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java @@ -17,7 +17,7 @@ /** * Implementation of a node in a {@link DiffTree}. * - * Includes methods for creating a node by getting its code type and diff type and for getting the feature mapping of the node. + * Includes methods for creating a node by getting its node type and diff type and for getting the feature mapping of the node. * @author Paul Bittner, Sören Viegener, Benjamin Moosherr */ public class DiffNode { @@ -30,10 +30,10 @@ public class DiffNode { public final DiffType diffType; /** - * The code type of this node, which determines the type of the represented + * The node type of this node, which determines the type of the represented * element in the diff (e.g., mapping or artifact). */ - public final CodeType codeType; + public final NodeType nodeType; private boolean isMultilineMacro = false; @@ -73,30 +73,30 @@ public class DiffNode { /** * Creates a DiffNode with the given parameters. * @param diffType The type of change made to this node. - * @param codeType The type of this node (i.e., mapping or artifact). + * @param nodeType The type of this node (i.e., mapping or artifact). * @param fromLines The starting line number of the corresponding text. * @param toLines The ending line number of the corresponding text. * @param featureMapping The formula stored in this node. Should be null for code (/artifact) nodes. * @param label A text label containing information to identify the node (such as the corresponding source code). */ - public DiffNode(DiffType diffType, CodeType codeType, + public DiffNode(DiffType diffType, NodeType nodeType, DiffLineNumber fromLines, DiffLineNumber toLines, Node featureMapping, String label) { - this(diffType, codeType, fromLines, toLines, featureMapping, + this(diffType, nodeType, fromLines, toLines, featureMapping, new ArrayList(Arrays.asList(StringUtils.LINEBREAK_REGEX.split(label, -1)))); } /** - * The same as {@link DiffNode#DiffNode(DiffType, CodeType, DiffLineNumber, DiffLineNumber, Node, String)} + * The same as {@link DiffNode#DiffNode(DiffType, NodeType, DiffLineNumber, DiffLineNumber, Node, String)} * but with the label separated into different lines of text instead of as a single String with newlines. */ - public DiffNode(DiffType diffType, CodeType codeType, + public DiffNode(DiffType diffType, NodeType nodeType, DiffLineNumber fromLines, DiffLineNumber toLines, Node featureMapping, List lines) { this.childOrder = new ArrayList<>(); this.diffType = diffType; - this.codeType = codeType; + this.nodeType = nodeType; this.from.set(fromLines); this.to.set(toLines); this.featureMapping = featureMapping; @@ -110,7 +110,7 @@ public DiffNode(DiffType diffType, CodeType codeType, public static DiffNode createRoot() { return new DiffNode( DiffType.NON, - CodeType.ROOT, + NodeType.ROOT, new DiffLineNumber(1, 1, 1), DiffLineNumber.Invalid(), FixTrueFalse.True, @@ -120,11 +120,11 @@ public static DiffNode createRoot() { /** * Creates an artifact node with the given parameters. - * For parameter descriptions, see {@link DiffNode#DiffNode(DiffType, CodeType, DiffLineNumber, DiffLineNumber, Node, String)}. + * For parameter descriptions, see {@link DiffNode#DiffNode(DiffType, NodeType, DiffLineNumber, DiffLineNumber, Node, String)}. * The code parameter will be set as the node's label. */ public static DiffNode createCode(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, String code) { - return new DiffNode(diffType, CodeType.CODE, fromLines, toLines, null, code); + return new DiffNode(diffType, NodeType.CODE, fromLines, toLines, null, code); } /** @@ -132,7 +132,7 @@ public static DiffNode createCode(DiffType diffType, DiffLineNumber fromLines, D * given as a list of individual lines instead of a single String with linebreaks to identify newlines. */ public static DiffNode createCode(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, List lines) { - return new DiffNode(diffType, CodeType.CODE, fromLines, toLines, null, lines); + return new DiffNode(diffType, NodeType.CODE, fromLines, toLines, null, lines); } /** @@ -651,9 +651,9 @@ public Lines getLinesAfterEdit() { /** * Returns the formula that is stored in this node. - * The formula is null for artifact nodes (i.e., {@link CodeType#CODE}). + * The formula is null for artifact nodes (i.e., {@link NodeType#CODE}). * The formula is not null for mapping nodes - * @see CodeType#isMacro + * @see NodeType#isMacro */ public Node getDirectFeatureMapping() { return featureMapping; @@ -691,9 +691,9 @@ public boolean isMultilineMacro() { /** * Returns the full feature mapping formula of this node. - * The feature mapping of an {@link CodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. - * The feature mapping of {@link CodeType#ELSE} and {@link CodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link CodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. + * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. + * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @param parentOf Function that returns the parent of a node. * This function decides whether the before or after parent should be visited. @@ -717,7 +717,7 @@ private List getFeatureMappingClauses(final Function p if (ancestor.isElif()) { and.add(negate(ancestor.getDirectFeatureMapping())); } else { - throw new RuntimeException("Expected If or Elif above Else or Elif but got " + ancestor.codeType + " from " + ancestor); + throw new RuntimeException("Expected If or Elif above Else or Elif but got " + ancestor.nodeType + " from " + ancestor); // Assert.assertTrue(ancestor.isCode()); } ancestor = parentOf.apply(ancestor); @@ -745,9 +745,9 @@ private Node getFeatureMapping(Function parentOf) { /** * Returns the full feature mapping formula of this node before the edit. - * The feature mapping of an {@link CodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. - * The feature mapping of {@link CodeType#ELSE} and {@link CodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link CodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. + * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. + * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @return The feature mapping of this node for the given parent edges. */ @@ -757,9 +757,9 @@ public Node getBeforeFeatureMapping() { /** * Returns the full feature mapping formula of this node after the edit. - * The feature mapping of an {@link CodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. - * The feature mapping of {@link CodeType#ELSE} and {@link CodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link CodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. + * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. + * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @return The feature mapping of this node for the given parent edges. */ @@ -928,57 +928,57 @@ public DiffType getDiffType() { /** * Returns true if this node represents an ELIF macro. - * @see CodeType#ELIF + * @see NodeType#ELIF */ public boolean isElif() { - return this.codeType.equals(CodeType.ELIF); + return this.nodeType.equals(NodeType.ELIF); } /** * Returns true if this node represents a conditional annotation. - * @see CodeType#IF + * @see NodeType#IF */ public boolean isIf() { - return this.codeType.equals(CodeType.IF); + return this.nodeType.equals(NodeType.IF); } /** * Returns true if this node is an artifact node. - * @see CodeType#CODE + * @see NodeType#CODE */ public boolean isCode() { - return this.codeType.equals(CodeType.CODE); + return this.nodeType.equals(NodeType.CODE); } /** * Returns true if this node represents the end of an annotation block. * Such a node should not be part of any {@link DiffTree}. - * @see CodeType#ENDIF + * @see NodeType#ENDIF */ public boolean isEndif() { - return this.codeType.equals(CodeType.ENDIF); + return this.nodeType.equals(NodeType.ENDIF); } /** * Returns true if this node represents an ELSE macro. - * @see CodeType#ELSE + * @see NodeType#ELSE */ public boolean isElse() { - return this.codeType.equals(CodeType.ELSE); + return this.nodeType.equals(NodeType.ELSE); } /** - * Returns true if this node is a root node (i.e., it has {@link CodeType#ROOT}. + * Returns true if this node is a root node (i.e., it has {@link NodeType#ROOT}. */ public boolean isRoot() { - return this.codeType.equals(CodeType.ROOT); + return this.nodeType.equals(NodeType.ROOT); } /** - * Returns {@link CodeType#isMacro()} for this node's {@link DiffNode#codeType}. + * Returns {@link NodeType#isMacro()} for this node's {@link DiffNode#nodeType}. */ public boolean isMacro() { - return this.codeType.isMacro(); + return this.nodeType.isMacro(); } /** @@ -999,13 +999,13 @@ public int getID() { id <<= ID_OFFSET; id += diffType.ordinal(); id <<= ID_OFFSET; - id += codeType.ordinal(); + id += nodeType.ordinal(); return id; } /** * Reconstructs a node from the given id and sets the given label. - * An id uniquely determines a node's {@link DiffNode#codeType}, {@link DiffNode#diffType}, and {@link DiffLineNumber#inDiff line number in the diff}. + * An id uniquely determines a node's {@link DiffNode#nodeType}, {@link DiffNode#diffType}, and {@link DiffLineNumber#inDiff line number in the diff}. * The almost-inverse function is {@link DiffNode#getID()} but the conversion is not lossless. * @param id The id from which to reconstruct the node. * @param label The label the node should have. @@ -1014,13 +1014,13 @@ public int getID() { public static DiffNode fromID(final int id, String label) { final int lowestBitsMask = (1 << ID_OFFSET) - 1; - final int codeTypeOrdinal = id & lowestBitsMask; + final int nodeTypeOrdinal = id & lowestBitsMask; final int diffTypeOrdinal = (id >> ID_OFFSET) & lowestBitsMask; final int fromInDiff = (id >> (2*ID_OFFSET)) - 1; return new DiffNode( DiffType.values()[diffTypeOrdinal], - CodeType.values()[codeTypeOrdinal], + NodeType.values()[nodeTypeOrdinal], new DiffLineNumber(fromInDiff, DiffLineNumber.InvalidLineNumber, DiffLineNumber.InvalidLineNumber), DiffLineNumber.Invalid(), null, @@ -1117,7 +1117,7 @@ public String toTextDiff() { // Add endif after macro if (isMacro()) { diff - .append(toTextDiffLine(this.diffType, List.of(CodeType.ENDIF.asMacroText()))) + .append(toTextDiffLine(this.diffType, List.of(NodeType.ENDIF.asMacroText()))) .append(StringUtils.LINEBREAK); } @@ -1128,11 +1128,11 @@ public String toTextDiff() { public String toString() { String s; if (isCode()) { - s = String.format("%s_%s from %d to %d", diffType, codeType, from.inDiff, to.inDiff); + s = String.format("%s_%s from %d to %d", diffType, nodeType, from.inDiff, to.inDiff); } else if (isRoot()) { s = "ROOT"; } else { - s = String.format("%s_%s from %d to %d with \"%s\"", diffType, codeType, + s = String.format("%s_%s from %d to %d with \"%s\"", diffType, nodeType, from.inDiff, to.inDiff, featureMapping); } return s; @@ -1143,7 +1143,7 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DiffNode diffNode = (DiffNode) o; - return isMultilineMacro == diffNode.isMultilineMacro && diffType == diffNode.diffType && codeType == diffNode.codeType && from.equals(diffNode.from) && to.equals(diffNode.to) && Objects.equals(featureMapping, diffNode.featureMapping) && lines.equals(diffNode.lines); + return isMultilineMacro == diffNode.isMultilineMacro && diffType == diffNode.diffType && nodeType == diffNode.nodeType && from.equals(diffNode.from) && to.equals(diffNode.to) && Objects.equals(featureMapping, diffNode.featureMapping) && lines.equals(diffNode.lines); } /** @@ -1156,6 +1156,6 @@ public boolean equals(Object o) { */ @Override public int hashCode() { - return Objects.hash(diffType, codeType, isMultilineMacro, from, to, featureMapping, lines); + return Objects.hash(diffType, nodeType, isMultilineMacro, from, to, featureMapping, lines); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java index 9ae5107ad..9c1806916 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java @@ -73,7 +73,7 @@ public static DiffResult fromDiff(final String diff, boolean collapseM * So just lines preceded by "+", "-", or " " are expected. * @param p Path to a diff file. * @param collapseMultipleCodeLines Set to true if subsequent lines of source code with - * the same {@link CodeType type of change} should be + * the same {@link NodeType type of change} should be * collapsed into a single source code node representing * all lines at once. * @param ignoreEmptyLines Set to true if empty lines should not be included in the DiffTree. @@ -95,7 +95,7 @@ public static DiffResult fromFile(final Path p, boolean collapseMultip * So just lines preceded by "+", "-", or " " are expected. * @param diff The diff as text. Lines should be separated by a newline character. Each line should be preceded by either "+", "-", or " ". * @param collapseMultipleCodeLines Set to true if subsequent lines of source code with - * the same {@link CodeType type of change} should be + * the same {@link NodeType type of change} should be * collapsed into a single source code node representing * all lines at once. * @param ignoreEmptyLines Set to true if empty lines should not be included in the DiffTree. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/CodeType.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java similarity index 76% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/CodeType.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java index b81233f70..7b0fbdf59 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/CodeType.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java @@ -7,7 +7,7 @@ * The type of nodes in a {@link DiffTree}. * Corresponds to the tau function from our paper. */ -public enum CodeType { +public enum NodeType { // Mapping types IF("if"), ENDIF("endif"), @@ -21,32 +21,32 @@ public enum CodeType { ROOT("ROOT"); public final String name; - CodeType(String name) { + NodeType(String name) { this.name = name; } /** - * Returns true iff this code type represents a conditional feature annotation (i.e., if or elif). + * Returns true iff this node type represents a conditional feature annotation (i.e., if or elif). */ public boolean isConditionalMacro() { return this == IF || this == ELIF; } /** - * Returns true iff this code type represents a feature mapping. + * Returns true iff this node type represents a feature mapping. */ - public boolean isMacro() { + public boolean isAnnotation() { return this != ROOT && this != CODE; } final static Pattern annotationRegex = Pattern.compile("^[+-]?\\s*#\\s*(if|endif|else|elif)"); /** - * Parses the code type from a line taken from a text-based diff. + * Parses the node type from a line taken from a text-based diff. * @param line A line in a patch. * @return The type of edit of line. */ - public static CodeType ofDiffLine(String line) { + public static NodeType ofDiffLine(String line) { Matcher matcher = annotationRegex.matcher(line); if (matcher.find()) { String id = matcher.group(1); @@ -65,19 +65,19 @@ public static CodeType ofDiffLine(String line) { } /** - * Creates a CodeType from its value names. + * Creates a NodeType from its value names. * @see Enum#name() * @param name a string that equals the name of one value of this enum (ignoring case) - * @return The CodeType that has the given name + * @return The NodeType that has the given name */ - public static CodeType fromName(final String name) { - for (CodeType candidate : values()) { + public static NodeType fromName(final String name) { + for (NodeType candidate : values()) { if (candidate.toString().equalsIgnoreCase(name)) { return candidate; } } - throw new IllegalArgumentException("Given string \"" + name + "\" is not the name of a CodeType."); + throw new IllegalArgumentException("Given string \"" + name + "\" is not the name of a NodeType."); } /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java index f0dea18b1..a71efeb93 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java @@ -2,7 +2,7 @@ import org.prop4j.Node; import org.variantsync.diffdetective.diff.DiffLineNumber; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; import org.variantsync.diffdetective.feature.CPPAnnotationParser; @@ -23,15 +23,15 @@ public record DiffNodeParser(CPPAnnotationParser annotationParser) { * Parses the given line from a text-based diff to a DiffNode. * * @param diffLine The line which the new node represents. - * @return A DiffNode with a code type, diff type, label, and feature mapping. + * @return A DiffNode with a node type, diff type, label, and feature mapping. */ public DiffNode fromDiffLine(String diffLine) throws IllFormedAnnotationException { DiffType diffType = DiffType.ofDiffLine(diffLine); - CodeType codeType = CodeType.ofDiffLine(diffLine); + NodeType nodeType = NodeType.ofDiffLine(diffLine); String label = diffLine.isEmpty() ? diffLine : diffLine.substring(1); Node featureMapping; - if (codeType == CodeType.CODE || codeType == CodeType.ENDIF || codeType == CodeType.ELSE) { + if (nodeType == NodeType.CODE || nodeType == NodeType.ENDIF || nodeType == NodeType.ELSE) { featureMapping = null; } else { featureMapping = annotationParser.parseDiffLine(diffLine); @@ -40,7 +40,7 @@ public DiffNode fromDiffLine(String diffLine) throws IllFormedAnnotationExceptio ArrayList lines = new ArrayList<>(); lines.add(label); return new DiffNode( - diffType, codeType, + diffType, nodeType, DiffLineNumber.Invalid(), DiffLineNumber.Invalid(), featureMapping, lines); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java index 5d48c9102..c94a267e8 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java @@ -129,7 +129,7 @@ public static DiffResult createDiffTree( case NotMyDuty: break; } - // This gets the code type and diff type of the current line and creates a node + // This gets the node type and diff type of the current line and creates a node // Note that the node is not yet added to the diff tree. final DiffNode newNode; try { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java index 56d440ea4..b24b9474b 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.parse; import org.variantsync.diffdetective.diff.DiffLineNumber; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; @@ -81,8 +81,8 @@ ParseResult consume( if (continuesMultilineDefinition(line)) { // If this multiline macro line is a header... - final CodeType codeType = CodeType.ofDiffLine(line); - if (codeType.isConditionalMacro()) { + final NodeType nodeType = NodeType.ofDiffLine(line); + if (nodeType.isConditionalMacro()) { // ... create a new multi line macro to complete. if (!isAdd) { if (beforeMLMacro != null) { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java index 3b7e76ef4..af8930d16 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/LineGraphImport.java @@ -141,7 +141,7 @@ private static DiffTree parseDiffTree(final String lineGraph, final Path inFile, if (root != null) { throw new RuntimeException("Not a DiffTree but a DiffGraph: Got more than one root! Got \"" + root + "\" and \"" + v + "\"!"); } - if (v.codeType == CodeType.IF || v.codeType == CodeType.ROOT) { + if (v.nodeType == NodeType.IF || v.nodeType == NodeType.ROOT) { root = v; } else { throw new RuntimeException("Not a DiffTree but a DiffGraph: The node \"" + v + "\" is not labeled as ROOT or IF but has no parents!"); @@ -153,7 +153,7 @@ private static DiffTree parseDiffTree(final String lineGraph, final Path inFile, throw new RuntimeException("Not a DiffTree but a DiffGraph: No root found!"); } -// countRootTypes.merge(root.codeType, 1, Integer::sum); +// countRootTypes.merge(root.nodeType, 1, Integer::sum); return new DiffTree(root, diffTreeSource); } else { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java index f620c0943..7876d4099 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java @@ -4,16 +4,16 @@ import org.variantsync.diffdetective.util.FileUtils; /** - * Print CodeType and DiffType and Mappings if Macro and Text if Code. + * Print NodeType and DiffType and Mappings if Macro and Text if Code. * @author Paul Bittner, Kevin Jedelhauser */ public class DebugDiffNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(final DiffNode node) { - return node.diffType + "_" + node.codeType + "_\"" + + return node.diffType + "_" + node.nodeType + "_\"" + DiffNodeLabelPrettyfier.prettyPrintIfMacroOr( node, FileUtils.replaceLineEndings(node.getLabel().trim().replaceAll("\t", " "), "
")) + "\""; } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java index d4695e3f5..b9548bbde 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.diff.difftree.serialize.nodeformat; import org.prop4j.Node; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; /** @@ -10,13 +10,13 @@ public abstract class DiffNodeLabelPrettyfier { /** * Auxiliary method for {@link DiffNodeLabelPrettyfier#prettyPrintIfMacroOr(DiffNode, String)}. - * Returns a string starting with the nodes {@link DiffNode#codeType}, and its {@link DiffNode#getDirectFeatureMapping()} + * Returns a string starting with the nodes {@link DiffNode#nodeType}, and its {@link DiffNode#getDirectFeatureMapping()} * if it has a formula. * @param node The {@link DiffNode} to print. - * @return CodeType and {@link DiffNode::getDirectFeatureMapping} of the node in a single string, seperated by a space character. + * @return NodeType and {@link DiffNode::getDirectFeatureMapping} of the node in a single string, seperated by a space character. */ private static String prettyPrintTypeAndMapping(final DiffNode node) { - String result = node.codeType.name; + String result = node.nodeType.name; final Node fm = node.getDirectFeatureMapping(); if (fm != null) { result += " " + fm; @@ -26,18 +26,18 @@ private static String prettyPrintTypeAndMapping(final DiffNode node) { /** * Invokes {@link #prettyPrintTypeAndMapping(DiffNode)} if the given - * node {@link CodeType#isMacro() is a macro}, and returns the elseValue otherwise. + * node {@link NodeType#isMacro() is a macro}, and returns the elseValue otherwise. * @param node The {@link DiffNode} to prettyprint. * @param elseValue The value to return in case the given node is not a macro. * @return The generated label. */ public static String prettyPrintIfMacroOr(final DiffNode node, final String elseValue) { String result = ""; - if (node.codeType.isMacro()) { + if (node.nodeType.isMacro()) { result += prettyPrintTypeAndMapping(node); } else { result += elseValue; } return result; } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java index bdb3996d5..6114c3b1e 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; /** - * Produces labels of kind fromLine-toLine: CodeType, suffixed by the node's formula if it is a macro. + * Produces labels of kind fromLine-toLine: NodeType, suffixed by the node's formula if it is a macro. * The line numbers reference the line numbers in the diff. * @see DiffNode#getFromLine() * @see DiffNode#getToLine() @@ -13,7 +13,7 @@ public class FormulasAndLineNumbersNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(DiffNode node) { - final String lineNumbers = node.getFromLine().inDiff + "-" + node.getToLine().inDiff + ": " + node.codeType; + final String lineNumbers = node.getFromLine().inDiff + "-" + node.getToLine().inDiff + ": " + node.nodeType; if (node.isMacro()) { return lineNumbers + " " + node.getDirectFeatureMapping(); } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java index 8295371f6..8baddac05 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java @@ -3,15 +3,15 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; /** - * Print CodeType and DiffType and Mappings of Macros. - * The produced label will be CodeType_DiffType_"macro formula" for mapping nodes, - * and CodeType_DiffType_"" for non-mapping nodes. + * Print NodeType and DiffType and Mappings of Macros. + * The produced label will be NodeType"macro formula" for mapping nodes, + * and NodeType"" for non-mapping nodes. * @see DiffNodeLabelPrettyfier#prettyPrintIfMacroOr(DiffNode, String) * @author Paul Bittner, Kevin Jedelhauser */ public class MappingsDiffNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(final DiffNode node) { - return node.diffType + "_" + node.codeType + "_\"" + DiffNodeLabelPrettyfier.prettyPrintIfMacroOr(node, "") + "\""; + return node.diffType + "_" + node.nodeType + "_\"" + DiffNodeLabelPrettyfier.prettyPrintIfMacroOr(node, "") + "\""; } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/TypeDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/TypeDiffNodeFormat.java index 64692b8fa..b68527b97 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/TypeDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/TypeDiffNodeFormat.java @@ -3,12 +3,12 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; /** - * Labels are of the form CodeType_DiffType. + * Labels are of the form NodeType. * @author Paul Bittner, Kevin Jedelhauser */ public class TypeDiffNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(final DiffNode node) { - return node.diffType + "_" + node.codeType; + return node.diffType + "_" + node.nodeType; } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java index 71a04429c..01fb9e22f 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java @@ -11,7 +11,7 @@ * Contrary to its name, this transformation leaves a DiffTree's graph structure unchanged. * This transformation uses the {@link RelabelNodes} transformer to relabel all nodes. * All {@link DiffNode#isCode() artifact} nodes will be labeled by their respective elementary pattern. - * All other nodes will be labeled by the {@link org.variantsync.diffdetective.diff.difftree.CodeType#name name of their code type}. + * All other nodes will be labeled by the {@link org.variantsync.diffdetective.diff.difftree.NodeType#name name of their node type}. * @author Paul Bittner */ public class CollapseElementaryPatterns implements DiffTreeTransformer { @@ -27,7 +27,7 @@ public CollapseElementaryPatterns(final ElementaryPatternCatalogue patterns) { if (d.isCode()) { return patterns.match(d).getName(); } else { - return d.codeType.name; + return d.nodeType.name; } }); } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java index adc367e69..12a7fa890 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java @@ -2,7 +2,7 @@ import org.prop4j.And; import org.prop4j.Node; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffType; @@ -102,7 +102,7 @@ private static void collapseChain(Stack chain) { while (!chain.isEmpty()) { lastPopped = chain.pop(); - switch (lastPopped.codeType) { + switch (lastPopped.nodeType) { case IF -> featureMappings.add(lastPopped.getAfterFeatureMapping()); case ELSE, ELIF -> { @@ -114,7 +114,7 @@ private static void collapseChain(Stack chain) { } } case ROOT, CODE -> - throw new RuntimeException("Unexpected code type " + lastPopped.codeType + " within macro chain!"); + throw new RuntimeException("Unexpected node type " + lastPopped.nodeType + " within macro chain!"); case ENDIF -> {} } } @@ -127,7 +127,7 @@ private static void collapseChain(Stack chain) { ArrayList lines = new ArrayList(); lines.add("$Collapsed Nested Annotations$"); final DiffNode merged = new DiffNode( - DiffType.NON, CodeType.IF, + DiffType.NON, NodeType.IF, head.getFromLine(), head.getToLine(), new And(featureMappings.toArray()), lines); diff --git a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java index caa38be39..f143e42d7 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java @@ -10,12 +10,12 @@ public String toLabel(final DiffNode node) { if (node.isCode()) { return ProposedElementaryPatterns.Instance.match(node).getName() + "
" + node.getLabel(); } else { - return node.diffType + "_" + switch (node.codeType) { + return node.diffType + "_" + switch (node.nodeType) { case ROOT -> "r"; case IF -> "mapping
" + node.getLabel(); case ELSE -> "else"; case ELIF -> "elif
" + node.getLabel(); - default -> node.codeType + "
" + node.getLabel(); + default -> node.nodeType + "
" + node.getLabel(); }; } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java index ad4ddcd20..c676a1b78 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java @@ -1,6 +1,6 @@ package org.variantsync.diffdetective.mining.formats; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; @@ -12,7 +12,7 @@ /** * Analogous to {@link ReleaseMiningDiffNodeFormat} but produces human readable labels instead of using integers. * Code nodes are labeled with the name of their matched elementary pattern. - * Macro nodes are labeled with DIFFTYPE_CODETYPE (e.g., an added IF node gets the label ADD_IF). + * Macro nodes are labeled with DIFFTYPE_NODETYPE (e.g., an added IF node gets the label ADD_IF). */ public class DebugMiningDiffNodeFormat implements MiningNodeFormat { @Override @@ -20,30 +20,30 @@ public String toLabel(final DiffNode node) { if (node.isCode()) { return ProposedElementaryPatterns.Instance.match(node).getName(); } else if (node.isRoot()) { - return node.diffType + "_" + CodeType.IF; + return node.diffType + "_" + NodeType.IF; } else { - return node.diffType + "_" + node.codeType; + return node.diffType + "_" + node.nodeType; } } @Override - public Pair fromEncodedTypes(String tag) { + public Pair fromEncodedTypes(String tag) { // If the label starts with ADD, REM, or NON if (Arrays.stream(DiffType.values()).anyMatch(diffType -> tag.startsWith(diffType.toString()))) { // then it is a macro node final DiffType dt = DiffType.fromName(tag); - final int codeTypeBegin = tag.indexOf("_") + 1; - final CodeType ct = CodeType.fromName(tag.substring(codeTypeBegin)); - if (ct == CodeType.ROOT) { + final int nodeTypeBegin = tag.indexOf("_") + 1; + final NodeType nt = NodeType.fromName(tag.substring(nodeTypeBegin)); + if (nt == NodeType.ROOT) { throw new IllegalArgumentException("There should be no roots in mined patterns!"); } - return new Pair<>(dt, ct); + return new Pair<>(dt, nt); } else { final ElementaryPattern pattern = ProposedElementaryPatterns.Instance.fromName(tag).orElseThrow( () -> new IllegalStateException("Label \"" + tag + "\" is neither a macro label, nor an elementary pattern!") ); - return new Pair<>(pattern.getDiffType(), CodeType.CODE); + return new Pair<>(pattern.getDiffType(), NodeType.CODE); } } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java index 8f5fba211..98003a019 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.mining.formats; import org.variantsync.diffdetective.diff.DiffLineNumber; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; import org.variantsync.diffdetective.diff.difftree.serialize.nodeformat.DiffNodeLabelFormat; @@ -9,7 +9,7 @@ import org.variantsync.functjonal.Pair; public interface MiningNodeFormat extends DiffNodeLabelFormat { - Pair fromEncodedTypes(final String tag); + Pair fromEncodedTypes(final String tag); @Override default DiffNode fromLabelAndId(String lineGraphNodeLabel, int nodeId) { @@ -18,10 +18,10 @@ default DiffNode fromLabelAndId(String lineGraphNodeLabel, int nodeId) { final DiffLineNumber lineTo = new DiffLineNumber(nodeId, nodeId, nodeId); final String resultLabel = ""; - final Pair types = fromEncodedTypes(lineGraphNodeLabel); + final Pair types = fromEncodedTypes(lineGraphNodeLabel); lineFrom.as(types.first()); lineTo.as(types.first()); - if (types.second() == CodeType.CODE) { + if (types.second() == NodeType.CODE) { return DiffNode.createCode(types.first(), lineFrom, lineTo, resultLabel); } else { diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java index 651ab1f2c..0df071f2c 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java @@ -1,6 +1,6 @@ package org.variantsync.diffdetective.mining.formats; -import org.variantsync.diffdetective.diff.difftree.CodeType; +import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; @@ -12,11 +12,11 @@ * Formats for DiffNodes for mining. * The label of a node starts with c if it is a code node and with m (for macro) otherwise. * The label of code nodes is followed by the index of its matched elementary pattern. - * The label of diff nodes is followed by the ordinal of its diff type and the ordinal of its code type. + * The label of diff nodes is followed by the ordinal of its diff type and the ordinal of its node type. * * Examples: - * DiffNode with codeType=CODE and elementary pattern AddWithMapping gets the label "c1" because AddWithMapping has index 1. - * DiffNode with codeType=ELSE and difftype=REM gets the label "m23" because the ordinal or REM is 2 and the ordinal of ELSE is 3. + * DiffNode with nodeType=CODE and elementary pattern AddWithMapping gets the label "c1" because AddWithMapping has index 1. + * DiffNode with nodeType=ELSE and difftype=REM gets the label "m23" because the ordinal or REM is 2 and the ordinal of ELSE is 3. */ public class ReleaseMiningDiffNodeFormat implements MiningNodeFormat { public final static String CODE_PREFIX = "c"; @@ -41,30 +41,30 @@ public String toLabel(DiffNode node) { if (node.isCode()) { return CODE_PREFIX + toId(ProposedElementaryPatterns.Instance.match(node)); } else { - final CodeType codeType = node.isRoot() ? CodeType.IF : node.codeType; - return MACRO_PREFIX + node.diffType.ordinal() + codeType.ordinal(); + final NodeType nodeType = node.isRoot() ? NodeType.IF : node.nodeType; + return MACRO_PREFIX + node.diffType.ordinal() + nodeType.ordinal(); } } @Override - public Pair fromEncodedTypes(String tag) { + public Pair fromEncodedTypes(String tag) { if (tag.startsWith(CODE_PREFIX)) { final ElementaryPattern pattern = fromId(Integer.parseInt(tag.substring(CODE_PREFIX.length()))); - return new Pair<>(pattern.getDiffType(), CodeType.CODE); + return new Pair<>(pattern.getDiffType(), NodeType.CODE); } else { Assert.assertTrue(tag.startsWith(MACRO_PREFIX)); final int diffTypeBegin = MACRO_PREFIX.length(); - final int codeTypeBegin = diffTypeBegin + 1; + final int nodeTypeBegin = diffTypeBegin + 1; final DiffType diffType = DiffType.values()[Integer.parseInt( - tag.substring(diffTypeBegin, codeTypeBegin) + tag.substring(diffTypeBegin, nodeTypeBegin) )]; - final CodeType codeType = CodeType.values()[Integer.parseInt( - tag.substring(codeTypeBegin, codeTypeBegin + 1) + final NodeType nodeType = NodeType.values()[Integer.parseInt( + tag.substring(nodeTypeBegin, nodeTypeBegin + 1) )]; - if (codeType == CodeType.ROOT) { + if (nodeType == NodeType.ROOT) { throw new IllegalArgumentException("There should be no roots in mined patterns!"); } - return new Pair<>(diffType, codeType); + return new Pair<>(diffType, nodeType); } } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java index ea1018841..8664f98da 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java @@ -70,7 +70,7 @@ public static void main(String[] args) throws IOException { outputPath ); -// for (Map.Entry entry : LineGraphImport.countRootTypes.entrySet()) { +// for (Map.Entry entry : LineGraphImport.countRootTypes.entrySet()) { // System.out.println(entry); // } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java index 344f2f514..36f50e6c0 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java @@ -31,7 +31,7 @@ public DiffType getDiffType() { /** * Returns true iff given node matches this pattern. - * @param codeNode Node which has code type CODE and whose DiffType is the same as this patterns DiffType. + * @param codeNode Node which has node type CODE and whose DiffType is the same as this patterns DiffType. */ protected abstract boolean matchesCodeNode(DiffNode codeNode); diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java index b0c9b2901..b40a88993 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java @@ -35,7 +35,7 @@ public interface ElementaryPatternCatalogue { default ElementaryPattern match(DiffNode node) { if (!node.isCode()) { - throw new IllegalArgumentException("Expected a code node but got " + node.codeType + "!"); + throw new IllegalArgumentException("Expected a code node but got " + node.nodeType + "!"); } final List patternsToCheck = byType().get(node.diffType); diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java index c4cd95cf1..4844d0717 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java @@ -72,7 +72,7 @@ public ElementaryPattern match(DiffNode node) // Each returned value is not null but an actual pattern object. // Since the given node may be any node, we have proven that every node is classified by at least one pattern. if (!node.isCode()) { - throw new IllegalArgumentException("Expected a code node but got " + node.codeType + "!"); + throw new IllegalArgumentException("Expected a code node but got " + node.nodeType + "!"); } if (node.isAdd()) { diff --git a/src/test/java/TestLineNumbers.java b/src/test/java/TestLineNumbers.java index 3fe80c794..1b9677b7e 100644 --- a/src/test/java/TestLineNumbers.java +++ b/src/test/java/TestLineNumbers.java @@ -66,7 +66,7 @@ private static DiffTree loadFullDiff(final Path p) throws IOException { private static void printLineNumbers(final DiffTree diffTree) { diffTree.forAll(node -> System.out.println(node.diffType.symbol - + " " + node.codeType + + " " + node.nodeType + " \"" + node.getLabel().trim() + " with ID " + node.getID() + "\" old: " + node.getLinesBeforeEdit() From b7b7b81c2e50644ec2ce0d0f5340cc7fc9e55cda Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 16:05:08 +0200 Subject: [PATCH 11/19] Use the term 'annotation' instead of 'macro' --- .../diffdetective/diff/difftree/DiffNode.java | 14 +++++++------- .../diffdetective/diff/difftree/DiffTree.java | 2 +- .../diffdetective/diff/difftree/NodeType.java | 2 +- .../difftree/parse/MultiLineMacroParser.java | 2 +- .../nodeformat/DebugDiffNodeFormat.java | 4 ++-- .../nodeformat/DiffNodeLabelPrettyfier.java | 10 +++++----- .../FormulasAndLineNumbersNodeFormat.java | 4 ++-- .../nodeformat/MappingsDiffNodeFormat.java | 8 ++++---- ...=> CollapseNestedNonEditedAnnotations.java} | 18 +++++++++--------- .../transform/FeatureExpressionFilter.java | 6 +++--- .../diff/difftree/transform/Starfold.java | 12 ++++++------ .../diffdetective/mining/DiffTreeMiner.java | 4 ++-- .../mining/RunningExampleFinder.java | 2 +- .../formats/DebugMiningDiffNodeFormat.java | 6 +++--- .../formats/ReleaseMiningDiffNodeFormat.java | 8 ++++---- src/test/java/LinuxParsingTest.java | 2 +- 16 files changed, 52 insertions(+), 52 deletions(-) rename src/main/java/org/variantsync/diffdetective/diff/difftree/transform/{CollapseNestedNonEditedMacros.java => CollapseNestedNonEditedAnnotations.java} (89%) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java index b3df9c4b2..08c554cd2 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java @@ -653,7 +653,7 @@ public Lines getLinesAfterEdit() { * Returns the formula that is stored in this node. * The formula is null for artifact nodes (i.e., {@link NodeType#CODE}). * The formula is not null for mapping nodes - * @see NodeType#isMacro + * @see NodeType#isAnnotation */ public Node getDirectFeatureMapping() { return featureMapping; @@ -927,7 +927,7 @@ public DiffType getDiffType() { } /** - * Returns true if this node represents an ELIF macro. + * Returns true if this node represents an ELIF annotation. * @see NodeType#ELIF */ public boolean isElif() { @@ -960,7 +960,7 @@ public boolean isEndif() { } /** - * Returns true if this node represents an ELSE macro. + * Returns true if this node represents an ELSE annotation. * @see NodeType#ELSE */ public boolean isElse() { @@ -975,10 +975,10 @@ public boolean isRoot() { } /** - * Returns {@link NodeType#isMacro()} for this node's {@link DiffNode#nodeType}. + * Returns {@link NodeType#isAnnotation()} for this node's {@link DiffNode#nodeType}. */ - public boolean isMacro() { - return this.nodeType.isMacro(); + public boolean isAnnotation() { + return this.nodeType.isAnnotation(); } /** @@ -1115,7 +1115,7 @@ public String toTextDiff() { } // Add endif after macro - if (isMacro()) { + if (isAnnotation()) { diff .append(toTextDiffLine(this.diffType, List.of(NodeType.ENDIF.asMacroText()))) .append(StringUtils.LINEBREAK); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java index 9c1806916..ce8449943 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java @@ -214,7 +214,7 @@ public List computeCodeNodes() { * @see DiffTree#computeAllNodesThat */ public List computeAnnotationNodes() { - return computeAllNodesThat(DiffNode::isMacro); + return computeAllNodesThat(DiffNode::isAnnotation); } /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java index 7b0fbdf59..9a8a42e6f 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java @@ -28,7 +28,7 @@ public enum NodeType { /** * Returns true iff this node type represents a conditional feature annotation (i.e., if or elif). */ - public boolean isConditionalMacro() { + public boolean isConditionalAnnotation() { return this == IF || this == ELIF; } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java index b24b9474b..ffed678c7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java @@ -82,7 +82,7 @@ ParseResult consume( if (continuesMultilineDefinition(line)) { // If this multiline macro line is a header... final NodeType nodeType = NodeType.ofDiffLine(line); - if (nodeType.isConditionalMacro()) { + if (nodeType.isConditionalAnnotation()) { // ... create a new multi line macro to complete. if (!isAdd) { if (beforeMLMacro != null) { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java index 7876d4099..b0ff72643 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java @@ -4,14 +4,14 @@ import org.variantsync.diffdetective.util.FileUtils; /** - * Print NodeType and DiffType and Mappings if Macro and Text if Code. + * Print NodeType, DiffType and Mappings for Annotations and Text for Code. * @author Paul Bittner, Kevin Jedelhauser */ public class DebugDiffNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(final DiffNode node) { return node.diffType + "_" + node.nodeType + "_\"" + - DiffNodeLabelPrettyfier.prettyPrintIfMacroOr( + DiffNodeLabelPrettyfier.prettyPrintIfAnnotationOr( node, FileUtils.replaceLineEndings(node.getLabel().trim().replaceAll("\t", " "), "
")) + "\""; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java index b9548bbde..96a97e8db 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DiffNodeLabelPrettyfier.java @@ -9,7 +9,7 @@ */ public abstract class DiffNodeLabelPrettyfier { /** - * Auxiliary method for {@link DiffNodeLabelPrettyfier#prettyPrintIfMacroOr(DiffNode, String)}. + * Auxiliary method for {@link DiffNodeLabelPrettyfier#prettyPrintIfAnnotationOr(DiffNode, String)}. * Returns a string starting with the nodes {@link DiffNode#nodeType}, and its {@link DiffNode#getDirectFeatureMapping()} * if it has a formula. * @param node The {@link DiffNode} to print. @@ -26,14 +26,14 @@ private static String prettyPrintTypeAndMapping(final DiffNode node) { /** * Invokes {@link #prettyPrintTypeAndMapping(DiffNode)} if the given - * node {@link NodeType#isMacro() is a macro}, and returns the elseValue otherwise. + * node {@link NodeType#isAnnotation() is an annotation}, and returns the elseValue otherwise. * @param node The {@link DiffNode} to prettyprint. - * @param elseValue The value to return in case the given node is not a macro. + * @param elseValue The value to return in case the given node is not an annotation. * @return The generated label. */ - public static String prettyPrintIfMacroOr(final DiffNode node, final String elseValue) { + public static String prettyPrintIfAnnotationOr(final DiffNode node, final String elseValue) { String result = ""; - if (node.nodeType.isMacro()) { + if (node.nodeType.isAnnotation()) { result += prettyPrintTypeAndMapping(node); } else { result += elseValue; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java index 6114c3b1e..21d47929e 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/FormulasAndLineNumbersNodeFormat.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; /** - * Produces labels of kind fromLine-toLine: NodeType, suffixed by the node's formula if it is a macro. + * Produces labels of kind fromLine-toLine: NodeType, suffixed by the node's formula if it is an annotation. * The line numbers reference the line numbers in the diff. * @see DiffNode#getFromLine() * @see DiffNode#getToLine() @@ -14,7 +14,7 @@ public class FormulasAndLineNumbersNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(DiffNode node) { final String lineNumbers = node.getFromLine().inDiff + "-" + node.getToLine().inDiff + ": " + node.nodeType; - if (node.isMacro()) { + if (node.isAnnotation()) { return lineNumbers + " " + node.getDirectFeatureMapping(); } return lineNumbers; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java index 8baddac05..d3aae2ac2 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/MappingsDiffNodeFormat.java @@ -3,15 +3,15 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; /** - * Print NodeType and DiffType and Mappings of Macros. - * The produced label will be NodeType"macro formula" for mapping nodes, + * Print NodeType and DiffType and Mappings of Annotations. + * The produced label will be NodeType"annotation formula" for mapping nodes, * and NodeType"" for non-mapping nodes. - * @see DiffNodeLabelPrettyfier#prettyPrintIfMacroOr(DiffNode, String) + * @see DiffNodeLabelPrettyfier#prettyPrintIfAnnotationOr(DiffNode, String) * @author Paul Bittner, Kevin Jedelhauser */ public class MappingsDiffNodeFormat implements DiffNodeLabelFormat { @Override public String toLabel(final DiffNode node) { - return node.diffType + "_" + node.nodeType + "_\"" + DiffNodeLabelPrettyfier.prettyPrintIfMacroOr(node, "") + "\""; + return node.diffType + "_" + node.nodeType + "_\"" + DiffNodeLabelPrettyfier.prettyPrintIfAnnotationOr(node, "") + "\""; } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java similarity index 89% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java index 12a7fa890..a2ed538a7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedMacros.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java @@ -14,11 +14,11 @@ import java.util.Stack; /** - * Collapses chains of nested non-edited macros. - * Imagine a macro node that is unchanged and has the same parent before and after the edit that - * is again an unchanged macro node that has the same parent before and after the edit, and so on. - * Such chains NON_IF -> NON_IF -> NON_IF -> ... -> NON_IF can be collapsed - * into a single unchanged macro node with the formulas of all nodes combined (by AND). + * Collapses chains of nested non-edited annotations. + * Imagine a annotation node that is unchanged and has the same parent before and after the edit + * that is again an unchanged annotation node that has the same parent before and after the edit, + * and so on. Such chains NON_IF -> NON_IF -> NON_IF -> ... -> NON_IF can be collapsed + * into a single unchanged annotation node with the formulas of all nodes combined (by AND). * This collapse is realized by this transformer. * * Fun fact: We implemented this transformation because of the @@ -26,7 +26,7 @@ * * @author Paul Bittner */ -public class CollapseNestedNonEditedMacros implements DiffTreeTransformer { +public class CollapseNestedNonEditedAnnotations implements DiffTreeTransformer { private final List> chainCandidates = new ArrayList<>(); private final List> chains = new ArrayList<>(); @@ -66,7 +66,7 @@ private void finalize(Stack chain) { } private void findChains(DiffTreeTraversal traversal, DiffNode subtree) { - if (subtree.isNon() && subtree.isMacro()) { + if (subtree.isNon() && subtree.isAnnotation()) { if (isHead(subtree)) { final Stack s = new Stack<>(); s.push(subtree); @@ -114,7 +114,7 @@ private static void collapseChain(Stack chain) { } } case ROOT, CODE -> - throw new RuntimeException("Unexpected node type " + lastPopped.nodeType + " within macro chain!"); + throw new RuntimeException("Unexpected node type " + lastPopped.nodeType + " within annotation chain!"); case ENDIF -> {} } } @@ -178,6 +178,6 @@ private static boolean isEnd(DiffNode d) { @Override public String toString() { - return "CollapseNestedNonEditedMacros"; + return "CollapseNestedNonEditedAnnotations"; } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/FeatureExpressionFilter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/FeatureExpressionFilter.java index 9d4851d69..de4037243 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/FeatureExpressionFilter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/FeatureExpressionFilter.java @@ -17,13 +17,13 @@ public record FeatureExpressionFilter(Predicate isFeatureAnnotation) i public void transform(DiffTree diffTree) { final List illegalNodes = new ArrayList<>(); diffTree.forAll(node -> { - if (node.isMacro() && !isFeatureAnnotation.test(node)) { + if (node.isAnnotation() && !isFeatureAnnotation.test(node)) { illegalNodes.add(node); } }); - for (final DiffNode illegalMacro : illegalNodes) { - diffTree.removeNode(illegalMacro); + for (final DiffNode illegalAnnotation : illegalNodes) { + diffTree.removeNode(illegalAnnotation); } } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java index 1d1dffedb..c124dc279 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java @@ -12,7 +12,7 @@ /** * Starfold reduces redundancy in edited leaves. * It identifies stars and simplifies its arms. - * A star is a non-edited macro node together with all its children + * A star is a non-edited annotation node together with all its children * that are code nodes and leaves. * The Starfold collapses all these children to a single child for each time. * This means, all inserted star-children will be merged into a single child, and for deletions respectively. @@ -46,11 +46,11 @@ public static Starfold IgnoreNodeOrder() { @Override public void transform(DiffTree diffTree) { // All non-artifact nodes are potential roots of stars. - final List macroNodes = diffTree.computeAllNodesThat(Starfold::isStarRoot); -// System.out.println("Inspecting " + macroNodes.size() + " star roots."); - for (DiffNode macro : macroNodes) { -// System.out.println("Found star root " + macro); - foldStar(macro); + final List annotations = diffTree.computeAllNodesThat(Starfold::isStarRoot); +// System.out.println("Inspecting " + annotations.size() + " star roots."); + for (DiffNode annotation : annotations) { +// System.out.println("Found star root " + annotation); + foldStar(annotation); } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java index 58f0f2562..3e8b1f5a9 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java +++ b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java @@ -16,7 +16,7 @@ import org.variantsync.diffdetective.diff.difftree.serialize.GraphFormat; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.EdgeLabelFormat; import org.variantsync.diffdetective.diff.difftree.serialize.treeformat.CommitDiffDiffTreeLabelFormat; -import org.variantsync.diffdetective.diff.difftree.transform.CollapseNestedNonEditedMacros; +import org.variantsync.diffdetective.diff.difftree.transform.CollapseNestedNonEditedAnnotations; import org.variantsync.diffdetective.diff.difftree.transform.CutNonEditedSubtrees; import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.difftree.transform.Starfold; @@ -50,7 +50,7 @@ public static List Postprocessing(final Repository reposito RunningExampleFinder.DefaultExamplesDirectory.resolve(repository == null ? "unknown" : repository.getRepositoryName()) )); } - processing.add(new CollapseNestedNonEditedMacros()); + processing.add(new CollapseNestedNonEditedAnnotations()); processing.add(Starfold.IgnoreNodeOrder()); return processing; } diff --git a/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java b/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java index 6873c824c..665c2ece4 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java @@ -87,7 +87,7 @@ private static boolean hasAtLeastOneComplexFormulaBeforeTheEdit(final DiffTree d // We would like to have a complex formula in the tree (complex := not just a positive literal). return diffTree.anyMatch(n -> { // and the formula should be visible before the edit - if (n.isMacro() && !n.isAdd()) { + if (n.isAnnotation() && !n.isAdd()) { return isComplexFormula(n.getDirectFeatureMapping()); } diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java index c676a1b78..011a4191c 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java @@ -12,7 +12,7 @@ /** * Analogous to {@link ReleaseMiningDiffNodeFormat} but produces human readable labels instead of using integers. * Code nodes are labeled with the name of their matched elementary pattern. - * Macro nodes are labeled with DIFFTYPE_NODETYPE (e.g., an added IF node gets the label ADD_IF). + * Annotation nodes are labeled with DIFFTYPE_NODETYPE (e.g., an added IF node gets the label ADD_IF). */ public class DebugMiningDiffNodeFormat implements MiningNodeFormat { @Override @@ -30,7 +30,7 @@ public String toLabel(final DiffNode node) { public Pair fromEncodedTypes(String tag) { // If the label starts with ADD, REM, or NON if (Arrays.stream(DiffType.values()).anyMatch(diffType -> tag.startsWith(diffType.toString()))) { - // then it is a macro node + // then it is an annotation node final DiffType dt = DiffType.fromName(tag); final int nodeTypeBegin = tag.indexOf("_") + 1; final NodeType nt = NodeType.fromName(tag.substring(nodeTypeBegin)); @@ -40,7 +40,7 @@ public Pair fromEncodedTypes(String tag) { return new Pair<>(dt, nt); } else { final ElementaryPattern pattern = ProposedElementaryPatterns.Instance.fromName(tag).orElseThrow( - () -> new IllegalStateException("Label \"" + tag + "\" is neither a macro label, nor an elementary pattern!") + () -> new IllegalStateException("Label \"" + tag + "\" is neither an annotation label, nor an elementary pattern!") ); return new Pair<>(pattern.getDiffType(), NodeType.CODE); diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java index 0df071f2c..54964b33b 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java @@ -20,7 +20,7 @@ */ public class ReleaseMiningDiffNodeFormat implements MiningNodeFormat { public final static String CODE_PREFIX = "c"; - public final static String MACRO_PREFIX = "m"; + public final static String ANNOTATION_PREFIX = "m"; private static int toId(final ElementaryPattern p) { for (int i = 0; i < ProposedElementaryPatterns.All.size(); ++i) { @@ -42,7 +42,7 @@ public String toLabel(DiffNode node) { return CODE_PREFIX + toId(ProposedElementaryPatterns.Instance.match(node)); } else { final NodeType nodeType = node.isRoot() ? NodeType.IF : node.nodeType; - return MACRO_PREFIX + node.diffType.ordinal() + nodeType.ordinal(); + return ANNOTATION_PREFIX + node.diffType.ordinal() + nodeType.ordinal(); } } @@ -52,8 +52,8 @@ public Pair fromEncodedTypes(String tag) { final ElementaryPattern pattern = fromId(Integer.parseInt(tag.substring(CODE_PREFIX.length()))); return new Pair<>(pattern.getDiffType(), NodeType.CODE); } else { - Assert.assertTrue(tag.startsWith(MACRO_PREFIX)); - final int diffTypeBegin = MACRO_PREFIX.length(); + Assert.assertTrue(tag.startsWith(ANNOTATION_PREFIX)); + final int diffTypeBegin = ANNOTATION_PREFIX.length(); final int nodeTypeBegin = diffTypeBegin + 1; final DiffType diffType = DiffType.values()[Integer.parseInt( tag.substring(diffTypeBegin, nodeTypeBegin) diff --git a/src/test/java/LinuxParsingTest.java b/src/test/java/LinuxParsingTest.java index b2641f6fc..9bad73fe7 100644 --- a/src/test/java/LinuxParsingTest.java +++ b/src/test/java/LinuxParsingTest.java @@ -26,7 +26,7 @@ public void test1() throws IOException { // new FeatureExpressionFilter(LinuxKernel::isFeature).transform(t); t.forAll(n -> { - if (n.isMacro()) { + if (n.isAnnotation()) { Assert.assertTrue(n.getLabel().contains("CONFIG_"), () -> "Macro node " + n + " is not a feature annotation!"); } }); From f80925e3a7fd03f83999c902e0a0188b1c7e7a98 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 16:59:27 +0200 Subject: [PATCH 12/19] Use the term 'artifact' instead of 'code' Note the American English spelling. --- STATUS.md | 2 +- .../diffdetective/diff/difftree/DiffNode.java | 34 +++++++------- .../diffdetective/diff/difftree/DiffTree.java | 4 +- .../diffdetective/diff/difftree/DiffType.java | 12 ++--- .../diffdetective/diff/difftree/NodeType.java | 8 ++-- .../diff/difftree/filter/DiffTreeFilter.java | 10 ++--- .../diff/difftree/parse/DiffNodeParser.java | 2 +- .../diff/difftree/parse/DiffTreeParser.java | 24 +++++----- .../difftree/parse/MultiLineMacroParser.java | 2 +- .../diff/difftree/serialize/TikzExporter.java | 2 +- .../nodeformat/DebugDiffNodeFormat.java | 2 +- .../transform/CollapseElementaryPatterns.java | 6 +-- .../CollapseNestedNonEditedAnnotations.java | 2 +- ....java => NaiveMovedArtifactDetection.java} | 44 +++++++++---------- .../diff/difftree/transform/Starfold.java | 8 ++-- .../diffdetective/mining/DiffTreeMiner.java | 6 +-- .../diffdetective/mining/MiningTask.java | 2 +- .../mining/RWCompositePatternNodeFormat.java | 2 +- .../mining/RunningExampleFinder.java | 6 +-- .../formats/DebugMiningDiffNodeFormat.java | 6 +-- .../mining/formats/MiningNodeFormat.java | 4 +- .../formats/ReleaseMiningDiffNodeFormat.java | 18 ++++---- .../mining/postprocessing/Postprocessor.java | 2 +- .../pattern/elementary/ElementaryPattern.java | 9 ++-- .../ElementaryPatternCatalogue.java | 4 +- .../pattern/elementary/proposed/AddToPC.java | 2 +- .../elementary/proposed/AddWithMapping.java | 4 +- .../elementary/proposed/Generalization.java | 6 +-- .../proposed/ProposedElementaryPatterns.java | 4 +- .../elementary/proposed/Reconfiguration.java | 6 +-- .../elementary/proposed/Refactoring.java | 8 ++-- .../elementary/proposed/RemFromPC.java | 4 +- .../elementary/proposed/RemWithMapping.java | 4 +- .../elementary/proposed/Specialization.java | 6 +-- .../elementary/proposed/Untouched.java | 10 ++--- .../preliminary/analysis/TreeGDAnalyzer.java | 2 +- .../pattern/semantic/AddIfdefElif.java | 4 +- .../pattern/semantic/AddIfdefElse.java | 4 +- .../pattern/semantic/AddIfdefWrapElse.java | 4 +- .../pattern/semantic/AddIfdefWrapThen.java | 4 +- .../tablegen/styles/ShortTable.java | 2 +- .../validation/PatternValidationTask.java | 2 +- src/main/resources/tikz_header.tex | 2 +- src/test/java/ElementaryPatternsTest.java | 2 +- src/test/java/MarlinDebug.java | 4 +- src/test/java/MoveDetectionTest.java | 4 +- src/test/java/PCTest.java | 2 +- src/test/resources/serialize/expected.tex | 6 +-- 48 files changed, 159 insertions(+), 158 deletions(-) rename src/main/java/org/variantsync/diffdetective/diff/difftree/transform/{NaiveMovedCodeDetection.java => NaiveMovedArtifactDetection.java} (62%) diff --git a/STATUS.md b/STATUS.md index a85d30dda..f3dcc6a6c 100644 --- a/STATUS.md +++ b/STATUS.md @@ -28,7 +28,7 @@ The `proofs` Haskell project provides an extended formal specification of our th The library is accompanied by a small demo application that shows an example test case for our proof for completeness, by creating a variation tree diff from two variation trees and re-projecting them. ## Claims -We claim the _Artifacts Available_ badge as we made our artefacts publicly available on [Github][ddgithub] and [Zenodo][ddzenodo]. +We claim the _Artifacts Available_ badge as we made our artifacts publicly available on [Github][ddgithub] and [Zenodo][ddzenodo]. We claim the _Artifacts Evaluated Reusable_ badge as we implemented DiffDetective as a reusable library (see above). Furthermore, both DiffDetective and our Haskell formalization serve as reference implementations if researchers or practitioners want to reimplement our theory in other programming languages. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java index 08c554cd2..4b6039c99 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffNode.java @@ -76,7 +76,7 @@ public class DiffNode { * @param nodeType The type of this node (i.e., mapping or artifact). * @param fromLines The starting line number of the corresponding text. * @param toLines The ending line number of the corresponding text. - * @param featureMapping The formula stored in this node. Should be null for code (/artifact) nodes. + * @param featureMapping The formula stored in this node. Should be null for artifact nodes. * @param label A text label containing information to identify the node (such as the corresponding source code). */ public DiffNode(DiffType diffType, NodeType nodeType, @@ -123,16 +123,16 @@ public static DiffNode createRoot() { * For parameter descriptions, see {@link DiffNode#DiffNode(DiffType, NodeType, DiffLineNumber, DiffLineNumber, Node, String)}. * The code parameter will be set as the node's label. */ - public static DiffNode createCode(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, String code) { - return new DiffNode(diffType, NodeType.CODE, fromLines, toLines, null, code); + public static DiffNode createArtifact(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, String code) { + return new DiffNode(diffType, NodeType.ARTIFACT, fromLines, toLines, null, code); } /** - * The same as {@link DiffNode#createCode(DiffType, DiffLineNumber, DiffLineNumber, String)} but with the code for the label + * The same as {@link DiffNode#createArtifact(DiffType, DiffLineNumber, DiffLineNumber, String)} but with the code for the label * given as a list of individual lines instead of a single String with linebreaks to identify newlines. */ - public static DiffNode createCode(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, List lines) { - return new DiffNode(diffType, NodeType.CODE, fromLines, toLines, null, lines); + public static DiffNode createArtifact(DiffType diffType, DiffLineNumber fromLines, DiffLineNumber toLines, List lines) { + return new DiffNode(diffType, NodeType.ARTIFACT, fromLines, toLines, null, lines); } /** @@ -651,7 +651,7 @@ public Lines getLinesAfterEdit() { /** * Returns the formula that is stored in this node. - * The formula is null for artifact nodes (i.e., {@link NodeType#CODE}). + * The formula is null for artifact nodes (i.e., {@link NodeType#ARTIFACT}). * The formula is not null for mapping nodes * @see NodeType#isAnnotation */ @@ -693,7 +693,7 @@ public boolean isMultilineMacro() { * Returns the full feature mapping formula of this node. * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#ARTIFACT artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @param parentOf Function that returns the parent of a node. * This function decides whether the before or after parent should be visited. @@ -718,14 +718,14 @@ private List getFeatureMappingClauses(final Function p and.add(negate(ancestor.getDirectFeatureMapping())); } else { throw new RuntimeException("Expected If or Elif above Else or Elif but got " + ancestor.nodeType + " from " + ancestor); - // Assert.assertTrue(ancestor.isCode()); + // Assert.assertTrue(ancestor.isArtifact()); } ancestor = parentOf.apply(ancestor); } and.add(negate(ancestor.getDirectFeatureMapping())); return and; - } else if (isCode()) { + } else if (isArtifact()) { return parent.getFeatureMappingClauses(parentOf); } @@ -747,7 +747,7 @@ private Node getFeatureMapping(Function parentOf) { * Returns the full feature mapping formula of this node before the edit. * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#ARTIFACT artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @return The feature mapping of this node for the given parent edges. */ @@ -759,7 +759,7 @@ public Node getBeforeFeatureMapping() { * Returns the full feature mapping formula of this node after the edit. * The feature mapping of an {@link NodeType#IF} node is its {@link DiffNode#getDirectFeatureMapping direct feature mapping}. * The feature mapping of {@link NodeType#ELSE} and {@link NodeType#ELIF} nodes is determined by all formulas in the respective if-elif-else chain. - * The feature mapping of an {@link NodeType#CODE artifact} node is the feature mapping of its parent. + * The feature mapping of an {@link NodeType#ARTIFACT artifact} node is the feature mapping of its parent. * See Equation (1) in our paper (+ its extension to time for variation tree diffs described in Section 3.1). * @return The feature mapping of this node for the given parent edges. */ @@ -807,7 +807,7 @@ private List getPresenceCondition(Function parentOf) { } return clauses; - } else if (isCode()) { + } else if (isArtifact()) { return parent.getPresenceCondition(parentOf); } @@ -944,10 +944,10 @@ public boolean isIf() { /** * Returns true if this node is an artifact node. - * @see NodeType#CODE + * @see NodeType#ARTIFACT */ - public boolean isCode() { - return this.nodeType.equals(NodeType.CODE); + public boolean isArtifact() { + return this.nodeType.equals(NodeType.ARTIFACT); } /** @@ -1127,7 +1127,7 @@ public String toTextDiff() { @Override public String toString() { String s; - if (isCode()) { + if (isArtifact()) { s = String.format("%s_%s from %d to %d", diffType, nodeType, from.inDiff, to.inDiff); } else if (isRoot()) { s = "ROOT"; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java index ce8449943..3dada3388 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffTree.java @@ -205,8 +205,8 @@ public List computeAllNodesThat(final Predicate property) { * Returns all artifact nodes of this DiffTree. * @see DiffTree#computeAllNodesThat */ - public List computeCodeNodes() { - return computeAllNodesThat(DiffNode::isCode); + public List computeArtifactNodes() { + return computeAllNodesThat(DiffNode::isArtifact); } /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffType.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffType.java index 0056253df..a2f917889 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffType.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/DiffType.java @@ -32,12 +32,12 @@ public static DiffType thatExistsOnlyAt(Time time) { /** * Runs the given procedure depending whether this diff types exists at the respective times. - * Runs the first given procedure if the edited artefact existed before the edit (DiffType != ADD). - * Runs the second given procedure if the edited artefact exists after the edit (DiffType != REM). - * Note: Runs both procedures sequentially if the artefact was not edited and thus + * Runs the first given procedure if the edited artifact existed before the edit (DiffType != ADD). + * Runs the second given procedure if the edited artifact exists after the edit (DiffType != REM). + * Note: Runs both procedures sequentially if the artifact was not edited and thus * exists before and after the edit (DiffType = NON). - * @param ifExistsBefore Procedure to run if the edited artefact existed before the edit (DiffType != ADD). - * @param ifExistsAfter Procedure to run if the edited artefact exists after the edit (DiffType != REM). + * @param ifExistsBefore Procedure to run if the edited artifact existed before the edit (DiffType != ADD). + * @param ifExistsAfter Procedure to run if the edited artifact exists after the edit (DiffType != REM). */ public void matchBeforeAfter(final Runnable ifExistsBefore, final Runnable ifExistsAfter) { if (this != DiffType.ADD) { @@ -52,7 +52,7 @@ public void matchBeforeAfter(final Runnable ifExistsBefore, final Runnable ifExi * Runs the given task once for each argument that would exist at a certain time if it had this diff type. * Runs task on ifExistsBefore if the value existed before the edit (DiffType != ADD). * Runs task on ifExistsAfter if the value exists after the edit (DiffType != ADD). - * Note: Runs task on both arguments sequentially if the artefact was not edited (DiffType == NON). + * Note: Runs task on both arguments sequentially if the artifact was not edited (DiffType == NON). * * @param ifExistsBefore Argument that is valid if the diff did not add. * @param ifExistsAfter Argument that is valid if the edit did not remove. diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java index 9a8a42e6f..ceea8a08b 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/NodeType.java @@ -14,8 +14,8 @@ public enum NodeType { ELSE("else"), ELIF("elif"), - // Code types - CODE("code"), + // Artifact types + ARTIFACT("artifact"), // Extra type for the root ROOT("ROOT"); @@ -36,7 +36,7 @@ public boolean isConditionalAnnotation() { * Returns true iff this node type represents a feature mapping. */ public boolean isAnnotation() { - return this != ROOT && this != CODE; + return this != ROOT && this != ARTIFACT; } final static Pattern annotationRegex = Pattern.compile("^[+-]?\\s*#\\s*(if|endif|else|elif)"); @@ -61,7 +61,7 @@ public static NodeType ofDiffLine(String line) { } } - return CODE; + return ARTIFACT; } /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java index 88b604ed5..c00747c58 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java @@ -28,13 +28,13 @@ public static TaggedPredicate Any() { /** * Returns a tagged predicate that returns true iff - * the DiffTree has more than one artifact node ({@link DiffNode#isCode()}. + * the DiffTree has more than one artifact node ({@link DiffNode#isArtifact()}. * The predicate is tagged with a String description of the predicate. */ - public static TaggedPredicate moreThanOneCodeNode() { + public static TaggedPredicate moreThanOneArtifactNode() { return new TaggedPredicate<>( "has more than one elementary pattern", - tree -> tree.count(DiffNode::isCode) > 1 + tree -> tree.count(DiffNode::isArtifact) > 1 ); } @@ -64,7 +64,7 @@ public static TaggedPredicate consistent() { /** * Returns a tagged predicate that returns true iff - * the DiffTree has at least one artifact node ({@link DiffNode#isCode()}) + * the DiffTree has at least one artifact node ({@link DiffNode#isArtifact()}) * that does not match any pattern of * {@link org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns#AddToPC}, * {@link org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns#RemFromPC}, @@ -75,7 +75,7 @@ public static TaggedPredicate hasAtLeastOneEditToVariability() return new TaggedPredicate<>( "has edits to variability", tree -> tree.anyMatch(n -> - n.isCode() && !AddToPC.matches(n) && !RemFromPC.matches(n) && !Untouched.matches(n) + n.isArtifact() && !AddToPC.matches(n) && !RemFromPC.matches(n) && !Untouched.matches(n) ) ); } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java index a71efeb93..b89344926 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffNodeParser.java @@ -31,7 +31,7 @@ public DiffNode fromDiffLine(String diffLine) throws IllFormedAnnotationExceptio String label = diffLine.isEmpty() ? diffLine : diffLine.substring(1); Node featureMapping; - if (nodeType == NodeType.CODE || nodeType == NodeType.ENDIF || nodeType == NodeType.ELSE) { + if (nodeType == NodeType.ARTIFACT || nodeType == NodeType.ENDIF || nodeType == NodeType.ELSE) { featureMapping = null; } else { featureMapping = annotationParser.parseDiffLine(diffLine); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java index c94a267e8..928d62947 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/DiffTreeParser.java @@ -55,7 +55,7 @@ public static DiffResult createDiffTree( * * @param fullDiff The full diff of a patch obtained from a buffered reader. * @param collapseMultipleCodeLines Whether multiple consecutive code lines with the same diff type - * should be collapsed into a single code node. + * should be collapsed into a single artifact node. * @param ignoreEmptyLines Whether empty lines (no matter if they are added removed * or remained unchanged) should be ignored. * @param nodeParser The parser to parse individual lines in the diff to DiffNodes. @@ -74,7 +74,7 @@ public static DiffResult createDiffTree( final DiffLineNumber lineNo = new DiffLineNumber(0, 0, 0); final DiffLineNumber lastLineNo = DiffLineNumber.Copy(lineNo); - DiffNode lastCode = null; + DiffNode lastArtifact = null; final AtomicReference> error = new AtomicReference<>(); final BiConsumer errorPropagation = (errType, message) -> { if (error.get() == null) { @@ -115,8 +115,8 @@ public static DiffResult createDiffTree( switch (isMLMacro.type()) { case Success: { - if (lastCode != null) { - lastCode = endCodeBlock(lastCode, lastLineNo); + if (lastArtifact != null) { + lastArtifact = endCodeBlock(lastArtifact, lastLineNo); } // This line belongs to a multiline macro and was handled, so go to the next line. continue; @@ -139,12 +139,12 @@ public static DiffResult createDiffTree( } // collapse multiple code lines - if (lastCode != null) { - if (collapseMultipleCodeLines && newNode.isCode() && lastCode.diffType.equals(newNode.diffType)) { - lastCode.addLines(newNode.getLines()); + if (lastArtifact != null) { + if (collapseMultipleCodeLines && newNode.isArtifact() && lastArtifact.diffType.equals(newNode.diffType)) { + lastArtifact.addLines(newNode.getLines()); continue; } else { - lastCode = endCodeBlock(lastCode, lastLineNo); + lastArtifact = endCodeBlock(lastArtifact, lastLineNo); } } @@ -154,8 +154,8 @@ public static DiffResult createDiffTree( nodes.add(newNode); } - if (newNode.isCode()) { - lastCode = newNode; + if (newNode.isArtifact()) { + lastArtifact = newNode; } else if (newNode.isEndif()) { final String currentLineFinal = currentLine; diffType.matchBeforeAfter(beforeStack, afterStack, @@ -187,8 +187,8 @@ public static DiffResult createDiffTree( return DiffResult.Failure(DiffError.NOT_ALL_ANNOTATIONS_CLOSED); } - if (lastCode != null) { - lastCode = endCodeBlock(lastCode, lineNo); + if (lastArtifact != null) { + lastArtifact = endCodeBlock(lastArtifact, lineNo); } endCodeBlock(root, lineNo); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java index ffed678c7..4702641eb 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/parse/MultiLineMacroParser.java @@ -103,7 +103,7 @@ ParseResult consume( /* If this happens (at least) one of this happened * 1. Found line of a multiline macro without header at line " + line + "! * 2. Backslash in a comment. - * 3. It is the head of a multiline #define macro that we classify as code. + * 3. It is the head of a multiline #define macro that we classify as artifact. * * As 2 and 3 are most likely we just assume those. */ diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java index 54cb293e0..fa03a22b2 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/TikzExporter.java @@ -98,7 +98,7 @@ public void exportDiffTree( .joining(" \\\\ ")); output.format("%n\t\\node[%s, %s] (node_%s) at (%s) {};%n", - node.isCode() ? "artefact" : "annotation", + node.isArtifact() ? "artifact" : "annotation", node.getDiffType().toString().toLowerCase(Locale.ROOT), node.getID(), node.getID()); diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java index b0ff72643..425025b16 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/serialize/nodeformat/DebugDiffNodeFormat.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.util.FileUtils; /** - * Print NodeType, DiffType and Mappings for Annotations and Text for Code. + * Print NodeType, DiffType and Mappings for Annotations and Text for Artifacts. * @author Paul Bittner, Kevin Jedelhauser */ public class DebugDiffNodeFormat implements DiffNodeLabelFormat { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java index 01fb9e22f..692dcd613 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java @@ -10,7 +10,7 @@ * Collapses elementary patterns in a DiffTree. * Contrary to its name, this transformation leaves a DiffTree's graph structure unchanged. * This transformation uses the {@link RelabelNodes} transformer to relabel all nodes. - * All {@link DiffNode#isCode() artifact} nodes will be labeled by their respective elementary pattern. + * All {@link DiffNode#isArtifact() artifact} nodes will be labeled by their respective elementary pattern. * All other nodes will be labeled by the {@link org.variantsync.diffdetective.diff.difftree.NodeType#name name of their node type}. * @author Paul Bittner */ @@ -19,12 +19,12 @@ public class CollapseElementaryPatterns implements DiffTreeTransformer { /** * Creates a new transformation that will use the given catalog of elementary patterns - * to relabel {@link DiffNode#isCode() artifact} nodes. + * to relabel {@link DiffNode#isArtifact() artifact} nodes. * @param patterns Catalog of patterns to match on artifact nodes. */ public CollapseElementaryPatterns(final ElementaryPatternCatalogue patterns) { relabelNodes = new RelabelNodes(d -> { - if (d.isCode()) { + if (d.isArtifact()) { return patterns.match(d).getName(); } else { return d.nodeType.name; diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java index a2ed538a7..4f42c67a4 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseNestedNonEditedAnnotations.java @@ -113,7 +113,7 @@ private static void collapseChain(Stack chain) { lastPopped = chain.pop(); } } - case ROOT, CODE -> + case ROOT, ARTIFACT -> throw new RuntimeException("Unexpected node type " + lastPopped.nodeType + " within annotation chain!"); case ENDIF -> {} } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedCodeDetection.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedArtifactDetection.java similarity index 62% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedCodeDetection.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedArtifactDetection.java index e6a48347c..9882b19ee 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedCodeDetection.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/NaiveMovedArtifactDetection.java @@ -10,16 +10,16 @@ import java.util.List; /** - * Finds code nodes whose label is exactly equal. If one of those nodes was added and the other one was removed, - * MovedCodeDetection merges them and interprets this edit as a move instead of separate insertion and deletion. - * A possible future extension would be to account for multiline code nodes to not only check for exact equality of text + * Finds artifact nodes whose label is exactly equal. If one of those nodes was added and the other one was removed, + * NaiveMovedArtifactDetection merges them and interprets this edit as a move instead of separate insertion and deletion. + * A possible future extension would be to account for multiline artifact nodes to not only check for exact equality of text * but for each line in the nodes individually. * @author Paul Bittner */ -public class NaiveMovedCodeDetection implements DiffTreeTransformer { +public class NaiveMovedArtifactDetection implements DiffTreeTransformer { @Override public void transform(final DiffTree diffTree) { - final List> twins = findCodeTwins(diffTree); + final List> twins = findArtifactTwins(diffTree); for (final Pair twin : twins) { final DiffNode added; @@ -46,22 +46,22 @@ public void transform(final DiffTree diffTree) { } } - private static List> findCodeTwins(final DiffTree diffTree) { - final List codeNodes = diffTree.computeCodeNodes(); + private static List> findArtifactTwins(final DiffTree diffTree) { + final List artifactNodes = diffTree.computeArtifactNodes(); final List> twins = new ArrayList<>(); - while (!codeNodes.isEmpty()) { + while (!artifactNodes.isEmpty()) { // Always inspect last element as it's the cheapest to remove. - final DiffNode code = codeNodes.get(codeNodes.size() - 1); - codeNodes.remove(code); + final DiffNode artifact = artifactNodes.get(artifactNodes.size() - 1); + artifactNodes.remove(artifact); // If the node was inserted or removed ... - if (!code.isNon()) { - // ... check if the opposite operation was applied to the same code somewhere else. - final DiffNode twin = findTwinOf(code, codeNodes); + if (!artifact.isNon()) { + // ... check if the opposite operation was applied to the same artifact somewhere else. + final DiffNode twin = findTwinOf(artifact, artifactNodes); if (twin != null) { - twins.add(new Pair<>(code, twin)); - codeNodes.remove(twin); + twins.add(new Pair<>(artifact, twin)); + artifactNodes.remove(twin); } } } @@ -69,17 +69,17 @@ private static List> findCodeTwins(final DiffTree diffT return twins; } - private static DiffNode findTwinOf(final DiffNode code, final List codeNodes) { - final DiffType weAreLookingFor = code.diffType.inverse(); - final String text = code.getLabel().trim(); + private static DiffNode findTwinOf(final DiffNode artifact, final List artifactNodes) { + final DiffType weAreLookingFor = artifact.diffType.inverse(); + final String text = artifact.getLabel().trim(); if (text.isEmpty()) { return null; } - // We assert the following as we removed the code node in transform. - // assert(!codeNodes.contains(code)); - for (final DiffNode other : codeNodes) { + // We assert the following as we removed the artifact node in transform. + // assert(!artifactNodes.contains(artifact)); + for (final DiffNode other : artifactNodes) { if (other.diffType == weAreLookingFor && text.equals(other.getLabel().trim())) { return other; } @@ -97,6 +97,6 @@ private static DiffNode merge(final DiffNode added, final DiffNode removed) { final DiffLineNumber from = new DiffLineNumber(Math.min(addFrom.inDiff, remFrom.inDiff), remFrom.beforeEdit, addFrom.afterEdit); final DiffLineNumber to = new DiffLineNumber(Math.max(addTo.inDiff, remTo.inDiff), remTo.beforeEdit, addTo.afterEdit); - return DiffNode.createCode(DiffType.NON, from, to, added.getLabel() /* equals removed.getText() */); + return DiffNode.createArtifact(DiffType.NON, from, to, added.getLabel() /* equals removed.getText() */); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java index c124dc279..1baae6711 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/Starfold.java @@ -13,7 +13,7 @@ * Starfold reduces redundancy in edited leaves. * It identifies stars and simplifies its arms. * A star is a non-edited annotation node together with all its children - * that are code nodes and leaves. + * that are artifact nodes and leaves. * The Starfold collapses all these children to a single child for each time. * This means, all inserted star-children will be merged into a single child, and for deletions respectively. * @author Paul Bittner, Benjamin Moosherr @@ -90,7 +90,7 @@ private void mergeArms(final DiffNode starRoot, Time time, final DiffType target final int targetIndex = starRoot.indexOfChild(starArms.get(0)); starRoot.removeChildren(starArms); starRoot.insertChildAt( - DiffNode.createCode( + DiffNode.createArtifact( targetDiffType, DiffLineNumber.Invalid(), DiffLineNumber.Invalid(), @@ -103,10 +103,10 @@ private void mergeArms(final DiffNode starRoot, Time time, final DiffType target } private static boolean isStarRoot(final DiffNode node) { - return !node.isCode() && node.isNon(); + return !node.isArtifact() && node.isNon(); } private static boolean isStarArm(final DiffNode node) { - return node.isLeaf() && node.isCode(); + return node.isLeaf() && node.isArtifact(); } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java index 3e8b1f5a9..eea3a1541 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java +++ b/src/main/java/org/variantsync/diffdetective/mining/DiffTreeMiner.java @@ -82,10 +82,10 @@ public static DiffTreeLineGraphExportOptions MiningExportOptions(final Repositor , EdgeFormat(nodeFormat) , new ExplainedFilter<>( DiffTreeFilter.notEmpty(), - DiffTreeFilter.moreThanOneCodeNode(), + DiffTreeFilter.moreThanOneArtifactNode(), /// We want to exclude patches that do not edit variability. - /// In particular, we noticed that most edits just insert or delete code (or replace it). - /// This is reasonable and was also observed in previous studies: Edits to code are more frequent than edits to variability. + /// In particular, we noticed that most edits just insert or delete artifacts (or replace it). + /// This is reasonable and was also observed in previous studies: Edits to artifacts are more frequent than edits to variability. /// Yet, such edits cannot reveal compositions of more complex edits to variability. /// We thus filter them. DiffTreeFilter.hasAtLeastOneEditToVariability() diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index 4f5922dc3..ef2c8df84 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -72,7 +72,7 @@ public AnalysisResult call() throws Exception { } t.forAll(node -> { - if (node.isCode()) { + if (node.isArtifact()) { final ElementaryPattern nodePattern = ProposedElementaryPatterns.Instance.match(node); miningResult.elementaryPatternCounts.reportOccurrenceFor( nodePattern, diff --git a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java index f143e42d7..1298dac31 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java @@ -7,7 +7,7 @@ public class RWCompositePatternNodeFormat extends DebugMiningDiffNodeFormat { @Override public String toLabel(final DiffNode node) { - if (node.isCode()) { + if (node.isArtifact()) { return ProposedElementaryPatterns.Instance.match(node).getName() + "
" + node.getLabel(); } else { return node.diffType + "_" + switch (node.nodeType) { diff --git a/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java b/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java index 665c2ece4..3027ba793 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RunningExampleFinder.java @@ -26,9 +26,9 @@ public class RunningExampleFinder { new TaggedPredicate<>("diff length <= " + DefaultMaxDiffLineCount, t -> diffIsNotLongerThan(t, DefaultMaxDiffLineCount)), new TaggedPredicate<>("has nesting before the edit", RunningExampleFinder::hasNestingBeforeEdit), new TaggedPredicate<>("has additions", t -> t.anyMatch(DiffNode::isAdd)), - new TaggedPredicate<>("code was edited", t -> t.anyMatch(n -> n.isCode() && !n.isNon())), + new TaggedPredicate<>("an artifact was edited", t -> t.anyMatch(n -> n.isArtifact() && !n.isNon())), DiffTreeFilter.hasAtLeastOneEditToVariability(), - DiffTreeFilter.moreThanOneCodeNode(), + DiffTreeFilter.moreThanOneArtifactNode(), new TaggedPredicate<>("has no annotated macros", t -> !RunningExampleFinder.hasAnnotatedMacros(t)), new TaggedPredicate<>("has a complex formula", RunningExampleFinder::hasAtLeastOneComplexFormulaBeforeTheEdit) ); @@ -72,7 +72,7 @@ private static boolean diffIsNotLongerThan(final DiffTree t, int maxLines) { } private static boolean hasAnnotatedMacros(final DiffTree diffTree) { - return diffTree.anyMatch(n -> n.isCode() && n.getLabel().trim().startsWith("#")); + return diffTree.anyMatch(n -> n.isArtifact() && n.getLabel().trim().startsWith("#")); } private static boolean hasNestingBeforeEdit(final DiffTree diffTree) { diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java index 011a4191c..f9f9ff8ea 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java @@ -11,13 +11,13 @@ /** * Analogous to {@link ReleaseMiningDiffNodeFormat} but produces human readable labels instead of using integers. - * Code nodes are labeled with the name of their matched elementary pattern. + * Artifact nodes are labeled with the name of their matched elementary pattern. * Annotation nodes are labeled with DIFFTYPE_NODETYPE (e.g., an added IF node gets the label ADD_IF). */ public class DebugMiningDiffNodeFormat implements MiningNodeFormat { @Override public String toLabel(final DiffNode node) { - if (node.isCode()) { + if (node.isArtifact()) { return ProposedElementaryPatterns.Instance.match(node).getName(); } else if (node.isRoot()) { return node.diffType + "_" + NodeType.IF; @@ -43,7 +43,7 @@ public Pair fromEncodedTypes(String tag) { () -> new IllegalStateException("Label \"" + tag + "\" is neither an annotation label, nor an elementary pattern!") ); - return new Pair<>(pattern.getDiffType(), NodeType.CODE); + return new Pair<>(pattern.getDiffType(), NodeType.ARTIFACT); } } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java index 98003a019..deb7080b1 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/MiningNodeFormat.java @@ -21,8 +21,8 @@ default DiffNode fromLabelAndId(String lineGraphNodeLabel, int nodeId) { final Pair types = fromEncodedTypes(lineGraphNodeLabel); lineFrom.as(types.first()); lineTo.as(types.first()); - if (types.second() == NodeType.CODE) { - return DiffNode.createCode(types.first(), + if (types.second() == NodeType.ARTIFACT) { + return DiffNode.createArtifact(types.first(), lineFrom, lineTo, resultLabel); } else { return new DiffNode(types.first(), types.second(), lineFrom, lineTo, FixTrueFalse.True, resultLabel); diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java index 54964b33b..046da4d79 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java @@ -10,16 +10,16 @@ /** * Formats for DiffNodes for mining. - * The label of a node starts with c if it is a code node and with m (for macro) otherwise. - * The label of code nodes is followed by the index of its matched elementary pattern. + * The label of a node starts with c (for code) if it is an artifact node and with m (for macro) otherwise. + * The label of artifact nodes is followed by the index of its matched elementary pattern. * The label of diff nodes is followed by the ordinal of its diff type and the ordinal of its node type. * * Examples: - * DiffNode with nodeType=CODE and elementary pattern AddWithMapping gets the label "c1" because AddWithMapping has index 1. + * DiffNode with nodeType=ARTIFACT and elementary pattern AddWithMapping gets the label "c1" because AddWithMapping has index 1. * DiffNode with nodeType=ELSE and difftype=REM gets the label "m23" because the ordinal or REM is 2 and the ordinal of ELSE is 3. */ public class ReleaseMiningDiffNodeFormat implements MiningNodeFormat { - public final static String CODE_PREFIX = "c"; + public final static String ARTIFACT_PREFIX = "c"; public final static String ANNOTATION_PREFIX = "m"; private static int toId(final ElementaryPattern p) { @@ -38,8 +38,8 @@ private static ElementaryPattern fromId(int id) { @Override public String toLabel(DiffNode node) { - if (node.isCode()) { - return CODE_PREFIX + toId(ProposedElementaryPatterns.Instance.match(node)); + if (node.isArtifact()) { + return ARTIFACT_PREFIX + toId(ProposedElementaryPatterns.Instance.match(node)); } else { final NodeType nodeType = node.isRoot() ? NodeType.IF : node.nodeType; return ANNOTATION_PREFIX + node.diffType.ordinal() + nodeType.ordinal(); @@ -48,9 +48,9 @@ public String toLabel(DiffNode node) { @Override public Pair fromEncodedTypes(String tag) { - if (tag.startsWith(CODE_PREFIX)) { - final ElementaryPattern pattern = fromId(Integer.parseInt(tag.substring(CODE_PREFIX.length()))); - return new Pair<>(pattern.getDiffType(), NodeType.CODE); + if (tag.startsWith(ARTIFACT_PREFIX)) { + final ElementaryPattern pattern = fromId(Integer.parseInt(tag.substring(ARTIFACT_PREFIX.length()))); + return new Pair<>(pattern.getDiffType(), NodeType.ARTIFACT); } else { Assert.assertTrue(tag.startsWith(ANNOTATION_PREFIX)); final int diffTypeBegin = ANNOTATION_PREFIX.length(); diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java index 3da49df2d..395a6836a 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java @@ -51,7 +51,7 @@ public static Postprocessor Default() { // Filter ill-formed patterns DiffTreeFilter.consistent(), // filter patterns containing less than two elementary patterns - DiffTreeFilter.moreThanOneCodeNode(), + DiffTreeFilter.moreThanOneArtifactNode(), DiffTreeFilter.hasAtLeastOneEditToVariability() ) ); diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java index 36f50e6c0..9b508d5bc 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java @@ -31,16 +31,17 @@ public DiffType getDiffType() { /** * Returns true iff given node matches this pattern. - * @param codeNode Node which has node type CODE and whose DiffType is the same as this patterns DiffType. + * @param artifactNode Node which has node type ARTIFACT and whose DiffType is the same as this + * patterns DiffType. */ - protected abstract boolean matchesCodeNode(DiffNode codeNode); + protected abstract boolean matchesArtifactNode(DiffNode artifactNode); /** - * Returns true if this pattern matches the given node and node is code. + * Returns true if this pattern matches the given node and is an artifact. */ @Override public final boolean matches(DiffNode node) { - return node.isCode() && node.diffType == diffType && matchesCodeNode(node); + return node.isArtifact() && node.diffType == diffType && matchesArtifactNode(node); } /** diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java index b40a88993..1a4b9c072 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java @@ -34,8 +34,8 @@ public interface ElementaryPatternCatalogue { */ default ElementaryPattern match(DiffNode node) { - if (!node.isCode()) { - throw new IllegalArgumentException("Expected a code node but got " + node.nodeType + "!"); + if (!node.isArtifact()) { + throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!"); } final List patternsToCheck = byType().get(node.diffType); diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java index dac7b4e78..e52f76280 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java @@ -14,7 +14,7 @@ final class AddToPC extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode node) { + protected boolean matchesArtifactNode(DiffNode node) { return !node.getAfterParent().isAdd(); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java index 88a933a2b..1f2d57b89 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java @@ -14,7 +14,7 @@ final class AddWithMapping extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - return codeNode.getAfterParent().isAdd(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + return artifactNode.getAfterParent().isAdd(); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java index 10bdc6ef9..9b6e0ef46 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java @@ -16,9 +16,9 @@ final class Generalization extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - final Node pcb = codeNode.getBeforeFeatureMapping(); - final Node pca = codeNode.getAfterFeatureMapping(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + final Node pcb = artifactNode.getBeforeFeatureMapping(); + final Node pca = artifactNode.getAfterFeatureMapping(); return SAT.implies(pcb, pca) && !SAT.implies(pca, pcb); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java index 4844d0717..3285c39e5 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java @@ -71,8 +71,8 @@ public ElementaryPattern match(DiffNode node) // Because this compiles, we know that each branch terminates and returns a value. // Each returned value is not null but an actual pattern object. // Since the given node may be any node, we have proven that every node is classified by at least one pattern. - if (!node.isCode()) { - throw new IllegalArgumentException("Expected a code node but got " + node.nodeType + "!"); + if (!node.isArtifact()) { + throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!"); } if (node.isAdd()) { diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java index 28a829328..cd7f25fc9 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java @@ -16,9 +16,9 @@ final class Reconfiguration extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - final Node pcb = codeNode.getBeforeFeatureMapping(); - final Node pca = codeNode.getAfterFeatureMapping(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + final Node pcb = artifactNode.getBeforeFeatureMapping(); + final Node pca = artifactNode.getAfterFeatureMapping(); return !SAT.implies(pcb, pca) && !SAT.implies(pca, pcb); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java index f0067f44a..7d5e73235 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java @@ -16,9 +16,9 @@ final class Refactoring extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - final Node pcb = codeNode.getBeforeFeatureMapping(); - final Node pca = codeNode.getAfterFeatureMapping(); - return SAT.equivalent(pcb, pca) && !codeNode.beforePathEqualsAfterPath(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + final Node pcb = artifactNode.getBeforeFeatureMapping(); + final Node pca = artifactNode.getAfterFeatureMapping(); + return SAT.equivalent(pcb, pca) && !artifactNode.beforePathEqualsAfterPath(); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java index 2e043a19a..15defdb65 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java @@ -14,7 +14,7 @@ final class RemFromPC extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - return !codeNode.getBeforeParent().isRem(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + return !artifactNode.getBeforeParent().isRem(); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java index 7ec0b6ae8..7a054ca99 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java @@ -14,7 +14,7 @@ final class RemWithMapping extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - return codeNode.getBeforeParent().isRem(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + return artifactNode.getBeforeParent().isRem(); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java index 1648b5555..f20543b49 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java @@ -16,9 +16,9 @@ final class Specialization extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - final Node pcb = codeNode.getBeforeFeatureMapping(); - final Node pca = codeNode.getAfterFeatureMapping(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + final Node pcb = artifactNode.getBeforeFeatureMapping(); + final Node pca = artifactNode.getAfterFeatureMapping(); return !SAT.implies(pcb, pca) && SAT.implies(pca, pcb); } } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java index 2e9269512..6cd4e513f 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java @@ -16,9 +16,9 @@ public class Untouched extends ElementaryPattern { } @Override - protected boolean matchesCodeNode(DiffNode codeNode) { - final Node pcb = codeNode.getBeforeFeatureMapping(); - final Node pca = codeNode.getAfterFeatureMapping(); - return SAT.equivalent(pcb, pca) && codeNode.beforePathEqualsAfterPath(); + protected boolean matchesArtifactNode(DiffNode artifactNode) { + final Node pcb = artifactNode.getBeforeFeatureMapping(); + final Node pca = artifactNode.getAfterFeatureMapping(); + return SAT.equivalent(pcb, pca) && artifactNode.beforePathEqualsAfterPath(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java index fc6ee0b3f..7852500e4 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java @@ -67,7 +67,7 @@ protected PatchDiffAnalysisResult analyzePatch(PatchDiff patchDiff) { DiffTree diffTree = patchDiff.getDiffTree(); if(diffTree != null) { // match atomic patterns - for (DiffNode diffNode : diffTree.computeCodeNodes()) { + for (DiffNode diffNode : diffTree.computeArtifactNodes()) { for (FeatureContextReverseEngineering pattern : patterns) { if (pattern.getPattern() instanceof ElementaryPattern) { results.add(pattern.createMatch(diffNode)); diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElif.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElif.java index 312c194c1..f649a2c23 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElif.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElif.java @@ -31,7 +31,7 @@ public Optional> match(DiffNode annotationNode) { boolean addedCodeInIf = false; DiffNode elifNode = null; for(DiffNode child : annotationNode.getAllChildren()){ - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCodeInIf = true; } if(child.isElif() && child.isAdd()){ @@ -60,7 +60,7 @@ private boolean isValidElif(DiffNode elifNode, List mappings) { DiffNode nextNode = null; for(DiffNode child : elifNode.getAllChildren()){ - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCode = true; } if((child.isElif() || child.isElse()) && child.isAdd()){ diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElse.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElse.java index 61ea00a65..e7552cb6d 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElse.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefElse.java @@ -30,7 +30,7 @@ public Optional> match(DiffNode annotationNode) { if(child.isElif()){ return Optional.empty(); } - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCodeInIf = true; } if(child.isElse() && child.isAdd()){ @@ -44,7 +44,7 @@ public Optional> match(DiffNode annotationNode) { boolean addedCodeInElse = false; for(DiffNode child : elseNode.getAllChildren()) { - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCodeInElse = true; } } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapElse.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapElse.java index 07857a3e9..de0746ee1 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapElse.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapElse.java @@ -29,7 +29,7 @@ public Optional> match(DiffNode annotationNode) { if(child.isElif()){ return Optional.empty(); } - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCodeInIf = true; } if(child.isElse() && child.isAdd()){ @@ -43,7 +43,7 @@ public Optional> match(DiffNode annotationNode) { boolean noneCodeInElse = false; for(DiffNode child : elseNode.getAllChildren()){ - if(child.isCode() && child.isNon()){ + if(child.isArtifact() && child.isNon()){ noneCodeInElse = true; } } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapThen.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapThen.java index 35d3291b2..ab673caae 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapThen.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/AddIfdefWrapThen.java @@ -30,7 +30,7 @@ public Optional> match(DiffNode annotationNode) { if(child.isElif()){ return Optional.empty(); } - if(child.isCode() && child.isNon()){ + if(child.isArtifact() && child.isNon()){ nonCodeInIf = true; } if(child.isElse() && child.isAdd()){ @@ -44,7 +44,7 @@ public Optional> match(DiffNode annotationNode) { boolean addedCodeInElse = false; for(DiffNode child : elseNode.getAllChildren()){ - if(child.isCode() && child.isAdd()){ + if(child.isArtifact() && child.isAdd()){ addedCodeInElse = true; } } diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java index 9b4def3d6..082226530 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java @@ -24,7 +24,7 @@ *
  • a dataset description *
  • commit counts *
  • diff counts - *
  • the number of artefact nodes + *
  • the number of artifact nodes *
  • elementary pattern counts, either absolute or relative to the total count of all patterns *
  • processing time * diff --git a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java index fee108007..775682081 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java @@ -74,7 +74,7 @@ public AnalysisResult call() throws Exception { } t.forAll(node -> { - if (node.isCode()) { + if (node.isArtifact()) { miningResult.elementaryPatternCounts.reportOccurrenceFor( ProposedElementaryPatterns.Instance.match(node), commitDiff diff --git a/src/main/resources/tikz_header.tex b/src/main/resources/tikz_header.tex index 9cbe189d5..3d021847a 100644 --- a/src/main/resources/tikz_header.tex +++ b/src/main/resources/tikz_header.tex @@ -41,7 +41,7 @@ \tikzset{ text centered, annotation/.style = {draw=vtdAnnotationBorderColor, circle, inner sep=0pt, minimum size=6.5mm, font=\footnotesize, line width=.4mm, fill=black!5}, - artefact/.style = {draw=vtdCodeColor, circle, inner sep=0pt, minimum size=6.5mm, font=\footnotesize, line width=.4mm, fill=black!5}, + artifact/.style = {draw=vtdCodeColor, circle, inner sep=0pt, minimum size=6.5mm, font=\footnotesize, line width=.4mm, fill=black!5}, non/.style = {}, add/.style = {fill=diffAddColour}, rem/.style = {fill=diffRemColour, dashed}, diff --git a/src/test/java/ElementaryPatternsTest.java b/src/test/java/ElementaryPatternsTest.java index 81a55281b..aafc76583 100644 --- a/src/test/java/ElementaryPatternsTest.java +++ b/src/test/java/ElementaryPatternsTest.java @@ -14,7 +14,7 @@ public void testAtomics() throws IOException { final Path path = testDir.resolve("elementary.diff"); final DiffTree t = DiffTree.fromFile(path, false, true).unwrap().getSuccess(); t.forAll(node -> { - if (node.isCode()) { + if (node.isArtifact()) { Assert.assertEquals( node.getLabel(), ProposedElementaryPatterns.Instance.match(node).getName() diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index 88625640e..59662fb06 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -102,7 +102,7 @@ public static void testCommit(final RepoInspection repoInspection, final String Logger.info(" Begin elementary pattern matching"); clock.start(); t.forAll(node -> { - if (node.isCode()) { + if (node.isArtifact()) { try { Logger.info(ProposedElementaryPatterns.Instance.match(node)); } catch (Exception e) { @@ -114,7 +114,7 @@ public static void testCommit(final RepoInspection repoInspection, final String Logger.info("isAdd: {}", node.isAdd()); Logger.info("isRem: {}", node.isRem()); Logger.info("isNon: {}", node.isNon()); - Logger.info("isCode: {}", node.isCode()); + Logger.info("isArtifact: {}", node.isArtifact()); // throw e; System.exit(0); } diff --git a/src/test/java/MoveDetectionTest.java b/src/test/java/MoveDetectionTest.java index 66e23a712..2ca98a82d 100644 --- a/src/test/java/MoveDetectionTest.java +++ b/src/test/java/MoveDetectionTest.java @@ -1,6 +1,6 @@ import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.render.DiffTreeRenderer; -import org.variantsync.diffdetective.diff.difftree.transform.NaiveMovedCodeDetection; +import org.variantsync.diffdetective.diff.difftree.transform.NaiveMovedArtifactDetection; import java.io.IOException; import java.nio.file.Path; @@ -14,7 +14,7 @@ public void simpleTest() throws IOException { final DiffTree t = DiffTree.fromFile(resDir.resolve("simple.txt"), true, true).unwrap().getSuccess(); final DiffTreeRenderer renderer = DiffTreeRenderer.WithinDiffDetective(); renderer.render(t, "MoveDetectionTestSimpleTest_Before", genDir); - new NaiveMovedCodeDetection().transform(t); + new NaiveMovedArtifactDetection().transform(t); renderer.render(t, "MoveDetectionTestSimpleTest_After", genDir); } } diff --git a/src/test/java/PCTest.java b/src/test/java/PCTest.java index c80857c16..f19f33231 100644 --- a/src/test/java/PCTest.java +++ b/src/test/java/PCTest.java @@ -57,7 +57,7 @@ private void test(final TestCase testCase) throws IOException { final Path path = testDir.resolve(testCase.file); final DiffTree t = DiffTree.fromFile(path, false, true).unwrap().getSuccess(); t.forAll(node -> { - if (node.isCode()) { + if (node.isArtifact()) { final String text = node.getLabel().trim(); final ExpectedPC expectedPC = testCase.expectedResult.getOrDefault(text, null); if (expectedPC != null) { diff --git a/src/test/resources/serialize/expected.tex b/src/test/resources/serialize/expected.tex index 1d957e43f..fddc14856 100644 --- a/src/test/resources/serialize/expected.tex +++ b/src/test/resources/serialize/expected.tex @@ -13,19 +13,19 @@ \node[annotation, non] (node_592) at (592) {}; \node[textbox] at (592) {\verb|8|}; - \node[artefact, add] (node_900) at (900) {}; + \node[artifact, add] (node_900) at (900) {}; \node[textbox] at (900) {\verb|13|}; \node[annotation, add] (node_3200) at (3200) {}; \node[textbox] at (3200) {\verb|49|}; - \node[artefact, non] (node_3284) at (3284) {}; + \node[artifact, non] (node_3284) at (3284) {}; \node[textbox] at (3284) {\verb|50|}; \node[annotation, add] (node_8192) at (8192) {}; \node[textbox] at (8192) {\verb|127|}; - \node[artefact, non] (node_8276) at (8276) {}; + \node[artifact, non] (node_8276) at (8276) {}; \node[textbox] at (8276) {\verb|128|}; \draw[vtdarrow] From 8aa8ea29847849cf813607c3532ba282b1850d21 Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 17:27:09 +0200 Subject: [PATCH 13/19] Flatten the pattern package The class EditPattern is renamed to EditClass and is moved to the preliminary package because there is no use outside of it. Unfortunately it cannot be removed easily because the preliminary would need many changes. --- .../diffdetective/analysis/AnalysisResult.java | 2 +- .../diffdetective/analysis/ElementaryPatternCount.java | 4 ++-- .../diffdetective/analysis/PatchStatistics.java | 2 +- .../diff/difftree/filter/DiffTreeFilter.java | 8 ++++---- .../difftree/transform/CollapseElementaryPatterns.java | 2 +- .../diffdetective/metadata/ElementaryPatternCount.java | 6 +++--- .../org/variantsync/diffdetective/mining/MiningTask.java | 4 ++-- .../mining/RWCompositePatternNodeFormat.java | 2 +- .../mining/formats/DebugMiningDiffNodeFormat.java | 4 ++-- .../mining/formats/ReleaseMiningDiffNodeFormat.java | 4 ++-- .../pattern/{elementary => }/ElementaryPattern.java | 8 ++++---- .../{elementary => }/ElementaryPatternCatalogue.java | 2 +- .../pattern/{elementary => }/proposed/AddToPC.java | 4 ++-- .../pattern/{elementary => }/proposed/AddWithMapping.java | 4 ++-- .../pattern/{elementary => }/proposed/Generalization.java | 4 ++-- .../proposed/ProposedElementaryPatterns.java | 6 +++--- .../{elementary => }/proposed/Reconfiguration.java | 4 ++-- .../pattern/{elementary => }/proposed/Refactoring.java | 4 ++-- .../pattern/{elementary => }/proposed/RemFromPC.java | 4 ++-- .../pattern/{elementary => }/proposed/RemWithMapping.java | 4 ++-- .../pattern/{elementary => }/proposed/Specialization.java | 4 ++-- .../pattern/{elementary => }/proposed/Untouched.java | 4 ++-- .../diffdetective/preliminary/analysis/GDAnalyzer.java | 6 +++--- .../preliminary/analysis/TreeGDAnalyzer.java | 2 +- .../preliminary/analysis/data/PatternMatch.java | 4 ++-- .../diffdetective/preliminary/evaluation/GDEvaluator.java | 6 +++--- .../pattern/FeatureContextReverseEngineering.java | 4 ++-- .../EditPattern.java => preliminary/pattern/Pattern.java} | 6 +++--- .../pattern/elementary/FeatureContextOfAddToPC.java | 6 +++--- .../elementary/FeatureContextOfAddWithMapping.java | 6 +++--- .../elementary/FeatureContextOfGeneralization.java | 6 +++--- .../elementary/FeatureContextOfReconfiguration.java | 6 +++--- .../pattern/elementary/FeatureContextOfRefactoring.java | 6 +++--- .../pattern/elementary/FeatureContextOfRemFromPC.java | 6 +++--- .../elementary/FeatureContextOfRemWithMapping.java | 6 +++--- .../elementary/FeatureContextOfSpecialization.java | 6 +++--- .../pattern/elementary/FeatureContextOfUntouched.java | 8 ++++---- .../preliminary/pattern/semantic/SemanticPattern.java | 6 +++--- .../diffdetective/tablegen/styles/ShortTable.java | 4 ++-- .../variantsync/diffdetective/tablegen/styles/Table1.java | 4 ++-- .../diffdetective/tablegen/styles/VariabilityShare.java | 4 ++-- .../diffdetective/validation/PatternValidationTask.java | 2 +- src/test/java/ElementaryPatternsTest.java | 2 +- src/test/java/MarlinDebug.java | 2 +- 44 files changed, 99 insertions(+), 99 deletions(-) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/ElementaryPattern.java (86%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/ElementaryPatternCatalogue.java (97%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/AddToPC.java (76%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/AddWithMapping.java (78%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/Generalization.java (83%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/ProposedElementaryPatterns.java (96%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/Reconfiguration.java (83%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/Refactoring.java (83%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/RemFromPC.java (77%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/RemWithMapping.java (78%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/Specialization.java (83%) rename src/main/java/org/variantsync/diffdetective/pattern/{elementary => }/proposed/Untouched.java (83%) rename src/main/java/org/variantsync/diffdetective/{pattern/EditPattern.java => preliminary/pattern/Pattern.java} (85%) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java b/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java index 80c6d1f5a..e2a207185 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java @@ -5,7 +5,7 @@ import org.variantsync.diffdetective.metadata.ElementaryPatternCount; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; import org.variantsync.diffdetective.metadata.Metadata; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.functjonal.Functjonal; import org.variantsync.functjonal.category.InplaceMonoid; import org.variantsync.functjonal.category.InplaceSemigroup; diff --git a/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java b/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java index ac8796d4f..759c6f8e5 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.analysis; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; import org.variantsync.diffdetective.util.CSV; import java.util.HashMap; diff --git a/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java b/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java index 18d439134..a433d3a08 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.analysis; import org.variantsync.diffdetective.diff.PatchDiff; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; import org.variantsync.diffdetective.util.CSV; /** diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java index c00747c58..2d8f57d4b 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import static org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns.*; +import static org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns.*; /** * A filter on DiffTrees that is equipped with some metadata T (e.g., for debugging or logging). @@ -66,9 +66,9 @@ public static TaggedPredicate consistent() { * Returns a tagged predicate that returns true iff * the DiffTree has at least one artifact node ({@link DiffNode#isArtifact()}) * that does not match any pattern of - * {@link org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns#AddToPC}, - * {@link org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns#RemFromPC}, - * {@link org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns#Untouched}. + * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#AddToPC}, + * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#RemFromPC}, + * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#Untouched}. * The predicate is tagged with a String description of the predicate. */ public static TaggedPredicate hasAtLeastOneEditToVariability() { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java index 692dcd613..0b57e1cf8 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; import java.util.List; diff --git a/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java b/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java index 91367e053..111d17e58 100644 --- a/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java +++ b/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java @@ -1,9 +1,9 @@ package org.variantsync.diffdetective.metadata; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPatternCatalogue; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.util.Assert; import org.variantsync.functjonal.Functjonal; import org.variantsync.functjonal.category.InplaceSemigroup; diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index ef2c8df84..971805981 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -11,8 +11,8 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.util.FileUtils; diff --git a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java index 1298dac31..f0d1f9831 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.mining.formats.DebugMiningDiffNodeFormat; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; public class RWCompositePatternNodeFormat extends DebugMiningDiffNodeFormat { @Override diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java index f9f9ff8ea..b6df74fa3 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java @@ -3,8 +3,8 @@ import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.functjonal.Pair; import java.util.Arrays; diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java index 046da4d79..37d61d4f1 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java @@ -3,8 +3,8 @@ import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.util.Assert; import org.variantsync.functjonal.Pair; diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java b/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java similarity index 86% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java rename to src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java index 9b508d5bc..dcd8878de 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPattern.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java @@ -1,20 +1,20 @@ -package org.variantsync.diffdetective.pattern.elementary; +package org.variantsync.diffdetective.pattern; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; /** * Abstract class for elementary edit pattern according to our ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -public abstract class ElementaryPattern extends EditPattern { +public abstract class ElementaryPattern extends Pattern { private final DiffType diffType; /** * Each elementary pattern handles exactly one DiffType. - * @param name unique identifier (see {@link EditPattern}). + * @param name unique identifier (see {@link Pattern}). * @param diffType This pattern matches only {@link DiffNode}s of the given {@link DiffType}. */ public ElementaryPattern(final String name, final DiffType diffType) { diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java b/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java similarity index 97% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java rename to src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java index 1a4b9c072..205a21e03 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java @@ -1,4 +1,4 @@ -package org.variantsync.diffdetective.pattern.elementary; +package org.variantsync.diffdetective.pattern; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java similarity index 76% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java index e52f76280..53c3abf47 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddToPC.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java @@ -1,8 +1,8 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our AddToPC pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java similarity index 78% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java index 1f2d57b89..ed172eda2 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/AddWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java @@ -1,8 +1,8 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our AddWithMapping pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java similarity index 83% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java index 9b6e0ef46..e0472a6e9 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Generalization.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java @@ -1,10 +1,10 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our Generalization pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java similarity index 96% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java index 3285c39e5..9bda874ec 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java @@ -1,11 +1,11 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; import org.variantsync.diffdetective.util.Assert; import java.util.*; diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java similarity index 83% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java index cd7f25fc9..b27a06e74 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Reconfiguration.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java @@ -1,10 +1,10 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our Reconfiguration pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java similarity index 83% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java index 7d5e73235..d2b337e2b 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Refactoring.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java @@ -1,10 +1,10 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our Refactoring pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java similarity index 77% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java index 15defdb65..0139c4860 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemFromPC.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java @@ -1,8 +1,8 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our RemFromPC pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java similarity index 78% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java index 7a054ca99..ec161f860 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/RemWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java @@ -1,8 +1,8 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our RemWithMapping pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java similarity index 83% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java index f20543b49..c6f4e5e86 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Specialization.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java @@ -1,10 +1,10 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our Specialization pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java similarity index 83% rename from src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java rename to src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java index 6cd4e513f..615b7bf3b 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/elementary/proposed/Untouched.java +++ b/src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java @@ -1,10 +1,10 @@ -package org.variantsync.diffdetective.pattern.elementary.proposed; +package org.variantsync.diffdetective.pattern.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; /** * Our Untouched pattern from the ESEC/FSE'22 paper. diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalyzer.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalyzer.java index eaa8bdc51..086b93c90 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalyzer.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalyzer.java @@ -2,7 +2,7 @@ import org.variantsync.diffdetective.diff.CommitDiff; import org.variantsync.diffdetective.diff.PatchDiff; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; import org.variantsync.diffdetective.preliminary.GitDiff; import org.variantsync.diffdetective.preliminary.analysis.data.CommitDiffAnalysisResult; import org.variantsync.diffdetective.preliminary.analysis.data.GDAnalysisResult; @@ -25,7 +25,7 @@ public abstract class GDAnalyzer { public GDAnalyzer(GitDiff gitDiff, List> patterns) { this.gitDiff = gitDiff; -// List> patternList = new ArrayList<>(Arrays.asList(patterns)); +// List> patternList = new ArrayList<>(Arrays.asList(patterns)); // patternList.add(0, new InvalidPatchPattern<>()); this.patterns = patterns; } @@ -34,7 +34,7 @@ public List> getReverseEngineerings() { return patterns; } - public List> getPatterns() { + public List> getPatterns() { return patterns.stream().map(FeatureContextReverseEngineering::getPattern).collect(Collectors.toList()); } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java index 7852500e4..2e00e1ba0 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; +import org.variantsync.diffdetective.pattern.ElementaryPattern; import org.variantsync.diffdetective.preliminary.GitDiff; import org.variantsync.diffdetective.preliminary.analysis.data.PatchDiffAnalysisResult; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/data/PatternMatch.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/data/PatternMatch.java index bda24c55c..7c9c9e421 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/data/PatternMatch.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/data/PatternMatch.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.preliminary.analysis.data; import org.prop4j.Node; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -50,7 +50,7 @@ public String getPatternName() { return pattern.getPattern().getName(); } - public EditPattern getPattern() { + public Pattern getPattern() { return pattern.getPattern(); } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java b/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java index 4c4dbb62e..3ecc7178f 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java @@ -8,7 +8,7 @@ import org.tinylog.Logger; import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; import org.variantsync.diffdetective.preliminary.analysis.GDAnalyzer; import org.variantsync.diffdetective.preliminary.analysis.data.CommitDiffAnalysisResult; import org.variantsync.diffdetective.preliminary.analysis.data.GDAnalysisResult; @@ -68,7 +68,7 @@ private List getEvaluations() { * @param patterns The patterns to search for * @return An int array containing the amount of matches for each pattern */ - public int[] getPatternCounts(List> patterns) { + public int[] getPatternCounts(List> patterns) { int[] patternCounts = new int[patterns.size()]; for (PatternMatchEvaluation pme : pmEvaluations) { @@ -105,7 +105,7 @@ public int[] getPatchesWithPatternCounts(List int[] getLineCounts(List> patterns) { + private int[] getLineCounts(List> patterns) { int[] lineCounts = new int[patterns.size()]; for (PatternMatchEvaluation pme : pmEvaluations) { diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/FeatureContextReverseEngineering.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/FeatureContextReverseEngineering.java index f93f7d364..17ad208bf 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/FeatureContextReverseEngineering.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/FeatureContextReverseEngineering.java @@ -1,6 +1,6 @@ package org.variantsync.diffdetective.preliminary.pattern; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; @@ -8,7 +8,7 @@ @Deprecated public interface FeatureContextReverseEngineering { - EditPattern getPattern(); + Pattern getPattern(); /** * Creates a PatternMatch object for the given element. * Assumes {@code matches(codeNode) == true}. diff --git a/src/main/java/org/variantsync/diffdetective/pattern/EditPattern.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/Pattern.java similarity index 85% rename from src/main/java/org/variantsync/diffdetective/pattern/EditPattern.java rename to src/main/java/org/variantsync/diffdetective/preliminary/pattern/Pattern.java index c832df8ee..cd0e021dd 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/EditPattern.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/Pattern.java @@ -1,4 +1,4 @@ -package org.variantsync.diffdetective.pattern; +package org.variantsync.diffdetective.preliminary.pattern; /** * Abstract class for edit patterns. @@ -6,7 +6,7 @@ * @param Type of elements on which the pattern may be matched. * @author Sören Viegener, Paul Bittner */ -public abstract class EditPattern { +public abstract class Pattern { /** * The name that uniquely identifies this pattern. */ @@ -16,7 +16,7 @@ public abstract class EditPattern { * Create a new pattern with the given name. * @param name Unique identifier. */ - public EditPattern(final String name) { + public Pattern(final String name) { this.name = name; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java index 671655574..074f0bd14 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java @@ -3,8 +3,8 @@ import org.prop4j.Node; import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ @Deprecated public final class FeatureContextOfAddToPC implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.AddToPC; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java index d2c63a6ab..65fbbb3ea 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java @@ -3,8 +3,8 @@ import org.prop4j.Node; import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ @Deprecated public final class FeatureContextOfAddWithMapping implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.AddWithMapping; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java index 4bf86a327..bceb3beb8 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java @@ -2,8 +2,8 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -11,7 +11,7 @@ @Deprecated public final class FeatureContextOfGeneralization implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.Generalization; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java index 8ce8e34f2..f75ab25cf 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java @@ -2,8 +2,8 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -11,7 +11,7 @@ @Deprecated public final class FeatureContextOfReconfiguration implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.Reconfiguration; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java index fda24e346..d277da625 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java @@ -2,8 +2,8 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -11,7 +11,7 @@ @Deprecated public final class FeatureContextOfRefactoring implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.Refactoring; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java index 8550745d2..8888e352c 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java @@ -3,8 +3,8 @@ import org.prop4j.Node; import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ @Deprecated public final class FeatureContextOfRemFromPC implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.RemFromPC; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java index d4e70f820..067a84074 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java @@ -3,8 +3,8 @@ import org.prop4j.Node; import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ @Deprecated public final class FeatureContextOfRemWithMapping implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.RemWithMapping; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java index f418034ed..d2357aa5a 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java @@ -2,8 +2,8 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -11,7 +11,7 @@ @Deprecated public final class FeatureContextOfSpecialization implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.Specialization; } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java index df3deead1..f4be6595d 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java @@ -2,8 +2,8 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -11,7 +11,7 @@ @Deprecated public class FeatureContextOfUntouched implements FeatureContextReverseEngineering { @Override - public EditPattern getPattern() { + public Pattern getPattern() { return ProposedElementaryPatterns.Untouched; } @@ -27,4 +27,4 @@ public PatternMatch createMatch(DiffNode codeNode) { public FeatureContext[] getFeatureContexts(PatternMatch patternMatch) { return new FeatureContext[0]; } -} \ No newline at end of file +} diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/SemanticPattern.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/SemanticPattern.java index 4194e582e..9aede0b44 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/SemanticPattern.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/semantic/SemanticPattern.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.preliminary.pattern.semantic; import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.pattern.EditPattern; +import org.variantsync.diffdetective.preliminary.pattern.Pattern; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -9,7 +9,7 @@ import java.util.Optional; @Deprecated -public abstract class SemanticPattern extends EditPattern implements FeatureContextReverseEngineering { +public abstract class SemanticPattern extends Pattern implements FeatureContextReverseEngineering { public static final SemanticPattern AddIfdefElif = new AddIfdefElif(); public static final SemanticPattern AddIfdefElse = new AddIfdefElse(); public static final SemanticPattern AddIfdefWrapElse = new AddIfdefWrapElse(); @@ -37,7 +37,7 @@ public PatternMatch createMatch(DiffNode diffNode) { } @Override - public EditPattern getPattern() { + public Pattern getPattern() { return this; } } diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java index 082226530..55484c8c4 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java @@ -2,8 +2,8 @@ import org.apache.commons.lang3.function.TriFunction; import org.variantsync.diffdetective.metadata.ElementaryPatternCount; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.tablegen.ColumnDefinition; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java index 1f64342b8..e2925abb1 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.tablegen.styles; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; import org.variantsync.diffdetective.tablegen.TableGenerator; diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java index 246a27ce2..f4abbff3e 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java @@ -1,8 +1,8 @@ package org.variantsync.diffdetective.tablegen.styles; import org.variantsync.diffdetective.metadata.ElementaryPatternCount; -import org.variantsync.diffdetective.pattern.elementary.ElementaryPattern; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; import org.variantsync.diffdetective.tablegen.rows.ContentRow; diff --git a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java index 775682081..fd3392914 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java @@ -13,7 +13,7 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.util.FileUtils; diff --git a/src/test/java/ElementaryPatternsTest.java b/src/test/java/ElementaryPatternsTest.java index aafc76583..5e05997ae 100644 --- a/src/test/java/ElementaryPatternsTest.java +++ b/src/test/java/ElementaryPatternsTest.java @@ -1,7 +1,7 @@ import org.junit.Assert; import org.junit.Test; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import java.io.IOException; import java.nio.file.Path; diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index 59662fb06..e2acbc02f 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -23,7 +23,7 @@ import org.variantsync.diffdetective.feature.CPPAnnotationParser; import org.variantsync.diffdetective.mining.DiffTreeMiner; import org.variantsync.diffdetective.mining.MiningTask; -import org.variantsync.diffdetective.pattern.elementary.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.validation.Validation; From 4025657219f1394abc385ef2e3dc8f1b9b2622af Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Wed, 14 Sep 2022 23:30:15 +0200 Subject: [PATCH 14/19] Use the term 'edit class' instead of 'elementary edit pattern' --- .../analysis/AnalysisResult.java | 22 ++--- .../analysis/EditClassCount.java | 46 ++++++++++ .../analysis/ElementaryPatternCount.java | 46 ---------- .../analysis/PatchStatistics.java | 16 ++-- .../diff/difftree/filter/DiffTreeFilter.java | 12 +-- ...Patterns.java => CollapseEditClasses.java} | 16 ++-- .../transform/CutNonEditedSubtrees.java | 2 +- .../EditClass.java} | 23 +++-- .../editclass/EditClassCatalogue.java | 61 +++++++++++++ .../proposed/AddToPC.java | 8 +- .../proposed/AddWithMapping.java | 8 +- .../proposed/Generalization.java | 8 +- .../proposed/ProposedEditClasses.java} | 68 +++++++-------- .../proposed/Reconfiguration.java | 8 +- .../proposed/Refactoring.java | 8 +- .../proposed/RemFromPC.java | 8 +- .../proposed/RemWithMapping.java | 8 +- .../proposed/Specialization.java | 8 +- .../proposed/Untouched.java | 8 +- ...yPatternCount.java => EditClassCount.java} | 85 ++++++++++--------- .../diffdetective/mining/MiningTask.java | 20 ++--- .../mining/RWCompositePatternNodeFormat.java | 4 +- .../formats/DebugMiningDiffNodeFormat.java | 16 ++-- .../formats/ReleaseMiningDiffNodeFormat.java | 26 +++--- .../postprocessing/MiningPostprocessing.java | 2 +- .../mining/postprocessing/Postprocessor.java | 3 +- .../pattern/ElementaryPatternCatalogue.java | 61 ------------- .../preliminary/analysis/TreeGDAnalyzer.java | 4 +- .../elementary/FeatureContextOfAddToPC.java | 4 +- .../FeatureContextOfAddWithMapping.java | 4 +- .../FeatureContextOfGeneralization.java | 4 +- .../FeatureContextOfReconfiguration.java | 4 +- .../FeatureContextOfRefactoring.java | 4 +- .../elementary/FeatureContextOfRemFromPC.java | 4 +- .../FeatureContextOfRemWithMapping.java | 4 +- .../FeatureContextOfSpecialization.java | 4 +- .../elementary/FeatureContextOfUntouched.java | 6 +- .../tablegen/MiningResultAccumulator.java | 4 +- .../tablegen/styles/ShortTable.java | 52 ++++++------ .../diffdetective/tablegen/styles/Table1.java | 10 +-- .../tablegen/styles/VariabilityShare.java | 32 +++---- ...Task.java => EditClassValidationTask.java} | 12 +-- .../diffdetective/validation/Validation.java | 4 +- ...PatternsTest.java => EditClassesTest.java} | 6 +- src/test/java/MarlinDebug.java | 4 +- 45 files changed, 383 insertions(+), 384 deletions(-) create mode 100644 src/main/java/org/variantsync/diffdetective/analysis/EditClassCount.java delete mode 100644 src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java rename src/main/java/org/variantsync/diffdetective/diff/difftree/transform/{CollapseElementaryPatterns.java => CollapseEditClasses.java} (72%) rename src/main/java/org/variantsync/diffdetective/{pattern/ElementaryPattern.java => editclass/EditClass.java} (56%) create mode 100644 src/main/java/org/variantsync/diffdetective/editclass/EditClassCatalogue.java rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/AddToPC.java (62%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/AddWithMapping.java (62%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/Generalization.java (72%) rename src/main/java/org/variantsync/diffdetective/{pattern/proposed/ProposedElementaryPatterns.java => editclass/proposed/ProposedEditClasses.java} (60%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/Reconfiguration.java (72%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/Refactoring.java (73%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/RemFromPC.java (63%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/RemWithMapping.java (62%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/Specialization.java (72%) rename src/main/java/org/variantsync/diffdetective/{pattern => editclass}/proposed/Untouched.java (73%) rename src/main/java/org/variantsync/diffdetective/metadata/{ElementaryPatternCount.java => EditClassCount.java} (58%) delete mode 100644 src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java rename src/main/java/org/variantsync/diffdetective/validation/{PatternValidationTask.java => EditClassValidationTask.java} (92%) rename src/test/java/{ElementaryPatternsTest.java => EditClassesTest.java} (76%) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java b/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java index e2a207185..548d5faf7 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/AnalysisResult.java @@ -2,10 +2,10 @@ import org.variantsync.diffdetective.diff.difftree.serialize.DiffTreeSerializeDebugData; import org.variantsync.diffdetective.diff.result.DiffError; -import org.variantsync.diffdetective.metadata.ElementaryPatternCount; +import org.variantsync.diffdetective.metadata.EditClassCount; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; import org.variantsync.diffdetective.metadata.Metadata; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.functjonal.Functjonal; import org.variantsync.functjonal.category.InplaceMonoid; import org.variantsync.functjonal.category.InplaceSemigroup; @@ -55,7 +55,7 @@ public class AnalysisResult implements Metadata { a.max.set(CommitProcessTime.max(a.max, b.max)); a.debugData.append(b.debugData); a.filterHits.append(b.filterHits); - a.elementaryPatternCounts.append(b.elementaryPatternCounts); + a.editClassCounts.append(b.editClassCounts); MergeMap.putAllValues(a.customInfo, b.customInfo, Semigroup.assertEquals()); a.diffErrors.append(b.diffErrors); }; @@ -80,7 +80,7 @@ public class AnalysisResult implements Metadata { public final CommitProcessTime min, max; public final DiffTreeSerializeDebugData debugData; public ExplainedFilterSummary filterHits; - public ElementaryPatternCount elementaryPatternCounts; + public EditClassCount editClassCounts; private final LinkedHashMap customInfo = new LinkedHashMap<>(); private final MergeMap diffErrors = new MergeMap<>(new HashMap<>(), Integer::sum); @@ -152,7 +152,7 @@ public AnalysisResult( this.runtimeWithMultithreadingInSeconds = runtimeWithMultithreadingInSeconds; this.debugData = debugData; this.filterHits = filterHits; - this.elementaryPatternCounts = new ElementaryPatternCount(); + this.editClassCounts = new EditClassCount(); this.min = min; this.max = max; } @@ -189,7 +189,7 @@ public static AnalysisResult importFrom(final Path p, final Map filterHitsLines = new ArrayList<>(); - final List elementaryPatternCountsLines = new ArrayList<>(); + final List editClassCountsLines = new ArrayList<>(); try (BufferedReader input = Files.newBufferedReader(p)) { // examine each line of the metadata file separately @@ -229,13 +229,13 @@ public static AnalysisResult importFrom(final Path p, final Map pattern.getName().equals(finalKey))) { - elementaryPatternCountsLines.add(line); + if (ProposedEditClasses.All.stream().anyMatch(editClass -> editClass.getName().equals(finalKey))) { + editClassCountsLines.add(line); } else if (key.startsWith(ExplainedFilterSummary.FILTERED_MESSAGE_BEGIN)) { filterHitsLines.add(line); } else if (key.startsWith(ERROR_BEGIN)) { @@ -257,7 +257,7 @@ public static AnalysisResult importFrom(final Path p, final Map snapshot() { snap.putAll(customInfo); snap.putAll(debugData.snapshot()); snap.putAll(filterHits.snapshot()); - snap.putAll(elementaryPatternCounts.snapshot()); + snap.putAll(editClassCounts.snapshot()); snap.putAll(Functjonal.bimap(diffErrors, error -> ERROR_BEGIN + error + ERROR_END, Object::toString)); return snap; } diff --git a/src/main/java/org/variantsync/diffdetective/analysis/EditClassCount.java b/src/main/java/org/variantsync/diffdetective/analysis/EditClassCount.java new file mode 100644 index 000000000..a07a2f378 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/analysis/EditClassCount.java @@ -0,0 +1,46 @@ +package org.variantsync.diffdetective.analysis; + +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.EditClassCatalogue; +import org.variantsync.diffdetective.util.CSV; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Gathers statistics about matching edit classes. + * @author Paul Bittner + */ +public class EditClassCount implements CSV { + private final EditClassCatalogue catalogue; + private final Map editClassCounts; + + /** + * Creates a new counter object for the given catalogue of edit classes. + * @param catalogue The catalogue whose edit classes to match and count. + */ + public EditClassCount(final EditClassCatalogue catalogue) { + this.catalogue = catalogue; + this.editClassCounts = new HashMap<>(); + catalogue.all().forEach(e -> editClassCounts.put(e, 0)); + } + + /** + * Increment the count for the given edit class. + * The given edit class is assumed to be part of this counts catalog. + * @see EditClassCount#EditClassCount(EditClassCatalogue) + * @param editClass The edit class whose count to increase by one. + */ + public void increment(final EditClass editClass) { + editClassCounts.computeIfPresent(editClass, (p, i) -> i + 1); + } + + @Override + public String toCSV(final String delimiter) { + return catalogue.all().stream() + .map(editClassCounts::get) + .map(Object::toString) + .collect(Collectors.joining(delimiter)); + } +} diff --git a/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java b/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java deleted file mode 100644 index 759c6f8e5..000000000 --- a/src/main/java/org/variantsync/diffdetective/analysis/ElementaryPatternCount.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.variantsync.diffdetective.analysis; - -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; -import org.variantsync.diffdetective.util.CSV; - -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * Class to gather statistics about matching elementary edit patterns. - * @author Paul Bittner - */ -public class ElementaryPatternCount implements CSV { - private final ElementaryPatternCatalogue catalogue; - private final Map patterncounts; - - /** - * Creates a new counter object for the given catalogue of elementary edit patterns. - * @param catalogue The catalogue whose patterns to match and count. - */ - public ElementaryPatternCount(final ElementaryPatternCatalogue catalogue) { - this.catalogue = catalogue; - this.patterncounts = new HashMap<>(); - catalogue.all().forEach(e -> patterncounts.put(e, 0)); - } - - /** - * Increment the count for the given elementary pattern. - * The given pattern is assumed to be part of this counts catalog. - * @see ElementaryPatternCount#ElementaryPatternCount(ElementaryPatternCatalogue) - * @param pattern The pattern whose count to increase by one. - */ - public void increment(final ElementaryPattern pattern) { - patterncounts.computeIfPresent(pattern, (p, i) -> i + 1); - } - - @Override - public String toCSV(final String delimiter) { - return catalogue.all().stream() - .map(patterncounts::get) - .map(Object::toString) - .collect(Collectors.joining(delimiter)); - } -} diff --git a/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java b/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java index a433d3a08..7150da219 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/PatchStatistics.java @@ -1,29 +1,29 @@ package org.variantsync.diffdetective.analysis; import org.variantsync.diffdetective.diff.PatchDiff; -import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.editclass.EditClassCatalogue; import org.variantsync.diffdetective.util.CSV; /** * Statistics for processing a patch in a commit. * @param patchDiff The diff of the processed patch. - * @param elementaryPatternCount Count statistics for the elementary edit patterns matched to the edits in the patch. + * @param editClassCount Count statistics for the edit class matched to the edits in the patch. * @author Paul Bittner */ public record PatchStatistics( PatchDiff patchDiff, - ElementaryPatternCount elementaryPatternCount) implements CSV { + EditClassCount editClassCount) implements CSV { /** - * Creates empty patch statistics for the given catalogue of edit patterns. + * Creates empty patch statistics for the given catalogue of edit classes. * @param patch The patch to gather statistics for. - * @param catalogue A catalogue of elementary edit patterns which should be used for classifying edits. + * @param catalogue A catalogue of edit classes which should be used for classifying edits. */ - public PatchStatistics(final PatchDiff patch, final ElementaryPatternCatalogue catalogue) { - this(patch, new ElementaryPatternCount(catalogue)); + public PatchStatistics(final PatchDiff patch, final EditClassCatalogue catalogue) { + this(patch, new EditClassCount(catalogue)); } @Override public String toCSV(final String delimiter) { - return patchDiff.getCommitHash() + delimiter + patchDiff.getFileName() + delimiter + elementaryPatternCount.toCSV(delimiter); + return patchDiff.getCommitHash() + delimiter + patchDiff.getFileName() + delimiter + editClassCount.toCSV(delimiter); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java index 2d8f57d4b..69b63feae 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/filter/DiffTreeFilter.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import static org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns.*; +import static org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses.*; /** * A filter on DiffTrees that is equipped with some metadata T (e.g., for debugging or logging). @@ -33,7 +33,7 @@ public static TaggedPredicate Any() { */ public static TaggedPredicate moreThanOneArtifactNode() { return new TaggedPredicate<>( - "has more than one elementary pattern", + "has more than one artifact node", tree -> tree.count(DiffNode::isArtifact) > 1 ); } @@ -65,10 +65,10 @@ public static TaggedPredicate consistent() { /** * Returns a tagged predicate that returns true iff * the DiffTree has at least one artifact node ({@link DiffNode#isArtifact()}) - * that does not match any pattern of - * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#AddToPC}, - * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#RemFromPC}, - * {@link org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns#Untouched}. + * that does not match any edit class of + * {@link org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses#AddToPC}, + * {@link org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses#RemFromPC}, + * {@link org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses#Untouched}. * The predicate is tagged with a String description of the predicate. */ public static TaggedPredicate hasAtLeastOneEditToVariability() { diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java similarity index 72% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java index 0b57e1cf8..e96a19c67 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java @@ -2,30 +2,30 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; +import org.variantsync.diffdetective.editclass.EditClassCatalogue; import java.util.List; /** - * Collapses elementary patterns in a DiffTree. + * Collapses edit classes in a DiffTree. * Contrary to its name, this transformation leaves a DiffTree's graph structure unchanged. * This transformation uses the {@link RelabelNodes} transformer to relabel all nodes. - * All {@link DiffNode#isArtifact() artifact} nodes will be labeled by their respective elementary pattern. + * All {@link DiffNode#isArtifact() artifact} nodes will be labeled by their respective edit class. * All other nodes will be labeled by the {@link org.variantsync.diffdetective.diff.difftree.NodeType#name name of their node type}. * @author Paul Bittner */ -public class CollapseElementaryPatterns implements DiffTreeTransformer { +public class CollapseEditClasses implements DiffTreeTransformer { private final DiffTreeTransformer relabelNodes; /** - * Creates a new transformation that will use the given catalog of elementary patterns + * Creates a new transformation that will use the given catalog of edit classes * to relabel {@link DiffNode#isArtifact() artifact} nodes. - * @param patterns Catalog of patterns to match on artifact nodes. + * @param editClasses Catalog of edit classes to match on artifact nodes. */ - public CollapseElementaryPatterns(final ElementaryPatternCatalogue patterns) { + public CollapseEditClasses(final EditClassCatalogue editClasses) { relabelNodes = new RelabelNodes(d -> { if (d.isArtifact()) { - return patterns.match(d).getName(); + return editClasses.match(d).getName(); } else { return d.nodeType.name; } diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CutNonEditedSubtrees.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CutNonEditedSubtrees.java index fae5e9ed8..cdc954813 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CutNonEditedSubtrees.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CutNonEditedSubtrees.java @@ -12,7 +12,7 @@ * A subtree is unedited, if all nodes in it are unchanged and all nodes have the same * before and after parent. * Such subtrees just model state but not an edit and thus are removed from the validation - * of our elementary edit patterns in our ESEC/FSE'22 paper. + * of our edit classes in our ESEC/FSE'22 paper. * @author Paul Bittner */ public class CutNonEditedSubtrees implements DiffTreeTransformer, DiffTreeVisitor { diff --git a/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java b/src/main/java/org/variantsync/diffdetective/editclass/EditClass.java similarity index 56% rename from src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java rename to src/main/java/org/variantsync/diffdetective/editclass/EditClass.java index dcd8878de..18cbb94f5 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPattern.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/EditClass.java @@ -1,4 +1,4 @@ -package org.variantsync.diffdetective.pattern; +package org.variantsync.diffdetective.editclass; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; @@ -6,38 +6,37 @@ import org.variantsync.diffdetective.preliminary.pattern.Pattern; /** - * Abstract class for elementary edit pattern according to our ESEC/FSE'22 paper. + * Abstract edit class according to our ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -public abstract class ElementaryPattern extends Pattern { +public abstract class EditClass extends Pattern { private final DiffType diffType; /** - * Each elementary pattern handles exactly one DiffType. + * Each edit class handles exactly one DiffType. * @param name unique identifier (see {@link Pattern}). - * @param diffType This pattern matches only {@link DiffNode}s of the given {@link DiffType}. + * @param diffType This edit class matches only {@link DiffNode}s of the given {@link DiffType}. */ - public ElementaryPattern(final String name, final DiffType diffType) { + public EditClass(final String name, final DiffType diffType) { super(name); this.diffType = diffType; } /** - * Returns the diff type nodes must have to be matched to this pattern. + * Returns the diff type nodes matched by this edit class. */ public DiffType getDiffType() { return diffType; } /** - * Returns true iff given node matches this pattern. - * @param artifactNode Node which has node type ARTIFACT and whose DiffType is the same as this - * patterns DiffType. + * Returns true iff the given node matches this edit class. + * @param artifactNode Node which has node type ARTIFACT and whose DiffType is the same as {@link getDiffType()}. */ protected abstract boolean matchesArtifactNode(DiffNode artifactNode); /** - * Returns true if this pattern matches the given node and is an artifact. + * Returns true if this edit class matches the given node and is an artifact. */ @Override public final boolean matches(DiffNode node) { @@ -45,7 +44,7 @@ public final boolean matches(DiffNode node) { } /** - * Returns true iff this pattern matches at leat one node on the given tree. + * Returns true iff this edit class matches at leat one node on the given tree. */ public boolean anyMatch(final DiffTree t) { return t.anyMatch(this::matches); diff --git a/src/main/java/org/variantsync/diffdetective/editclass/EditClassCatalogue.java b/src/main/java/org/variantsync/diffdetective/editclass/EditClassCatalogue.java new file mode 100644 index 000000000..3a1709e57 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/editclass/EditClassCatalogue.java @@ -0,0 +1,61 @@ +package org.variantsync.diffdetective.editclass; + +import org.variantsync.diffdetective.diff.difftree.DiffNode; +import org.variantsync.diffdetective.diff.difftree.DiffType; + +import java.util.List; +import java.util.Map; + +/** + * Interface for custom catalogs of edit classes. + * @author Paul Bittner + */ +public interface EditClassCatalogue { + /** + * Gives a list of all edit classes in this catalogue. + * The list should be constant and immutable (i.e., the very same list is returned each time all is invoked). + * The edit class should be immutable, too. + * @return a constant list of all edit classes in this catalogue. + */ + List all(); + + /** + * Returns a mapping from diff types to the edit classes that may match nodes of the given diff type. + * The returned map as well as all its values should be immutable and constant. * + * @return A classification of edit classes by their diff types. + */ + Map> byType(); + + /** + * Returns the edit class that matches the given node. + * Each node matches exactly one edit class. + * @param node The node of which to find its edit class. + * @return Returns the edit class that matches the given node. + */ + default EditClass match(DiffNode node) + { + if (!node.isArtifact()) { + throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!"); + } + + final List classessToCheck = byType().get(node.diffType); + + EditClass match = null; + for (final EditClass p : classessToCheck) { + if (p.matches(node)) { + if (match != null) { + throw new RuntimeException("BUG: Error in edit class definition!\n" + + "Node " + node + " matched " + match + " and " + p + "!"); + } + match = p; + } + } + + if (match == null) { + throw new RuntimeException("BUG: Error in edit class definition!\n" + + "Node " + node + " did not match any edit class!"); + } + + return match; + } +} diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/AddToPC.java similarity index 62% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/AddToPC.java index 53c3abf47..75eeb9dad 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddToPC.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/AddToPC.java @@ -1,14 +1,14 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our AddToPC pattern from the ESEC/FSE'22 paper. + * Our AddToPC edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class AddToPC extends ElementaryPattern { +final class AddToPC extends EditClass { AddToPC() { super("AddToPC", DiffType.ADD); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/AddWithMapping.java similarity index 62% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/AddWithMapping.java index ed172eda2..679a0255e 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/AddWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/AddWithMapping.java @@ -1,14 +1,14 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our AddWithMapping pattern from the ESEC/FSE'22 paper. + * Our AddWithMapping edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class AddWithMapping extends ElementaryPattern { +final class AddWithMapping extends EditClass { AddWithMapping() { super("AddWithMapping", DiffType.ADD); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Generalization.java similarity index 72% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/Generalization.java index e0472a6e9..8cfb6e4aa 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Generalization.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Generalization.java @@ -1,16 +1,16 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our Generalization pattern from the ESEC/FSE'22 paper. + * Our Generalization edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class Generalization extends ElementaryPattern { +final class Generalization extends EditClass { Generalization() { super("Generalization", DiffType.NON); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/ProposedEditClasses.java similarity index 60% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/ProposedEditClasses.java index 9bda874ec..f8a3f278a 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/ProposedElementaryPatterns.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/ProposedEditClasses.java @@ -1,76 +1,76 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; import org.variantsync.diffdetective.util.Assert; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.EditClassCatalogue; import java.util.*; /** - * The catalog of elementary edit patterns proposed in our ESEC/FSE'22 paper. + * The catalog of edit classes proposed in our ESEC/FSE'22 paper. * @author Paul Bittner */ -public class ProposedElementaryPatterns implements ElementaryPatternCatalogue { - public static final ElementaryPattern AddToPC = new AddToPC(); - public static final ElementaryPattern AddWithMapping = new AddWithMapping(); - public static final ElementaryPattern RemFromPC = new RemFromPC(); - public static final ElementaryPattern RemWithMapping = new RemWithMapping(); - public static final ElementaryPattern Specialization = new Specialization(); - public static final ElementaryPattern Generalization = new Generalization(); - public static final ElementaryPattern Reconfiguration = new Reconfiguration(); - public static final ElementaryPattern Refactoring = new Refactoring(); - public static final ElementaryPattern Untouched = new Untouched(); +public class ProposedEditClasses implements EditClassCatalogue { + public static final EditClass AddToPC = new AddToPC(); + public static final EditClass AddWithMapping = new AddWithMapping(); + public static final EditClass RemFromPC = new RemFromPC(); + public static final EditClass RemWithMapping = new RemWithMapping(); + public static final EditClass Specialization = new Specialization(); + public static final EditClass Generalization = new Generalization(); + public static final EditClass Reconfiguration = new Reconfiguration(); + public static final EditClass Refactoring = new Refactoring(); + public static final EditClass Untouched = new Untouched(); /** - * A list of all nine patterns in their order of appearance in the paper. + * A list of all nine edit classes in their order of appearance in the paper. */ - public static final List All = List.of( + public static final List All = List.of( AddToPC, AddWithMapping, RemFromPC, RemWithMapping, Specialization, Generalization, Reconfiguration, Refactoring, Untouched ); /** - * A map of all nine edit patterns, indexed by their DiffType. + * A map of all nine edit classes, indexed by their DiffType. */ - public static final Map> PatternsByType; + public static final Map> EditClassesByType; /** * Singleton instance of this catalog. */ - public static final ProposedElementaryPatterns Instance = new ProposedElementaryPatterns(); + public static final ProposedEditClasses Instance = new ProposedEditClasses(); static { - PatternsByType = new HashMap<>(); - for (final ElementaryPattern ap : All) { - PatternsByType.computeIfAbsent(ap.getDiffType(), d -> new ArrayList<>()).add(ap); + EditClassesByType = new HashMap<>(); + for (final EditClass ap : All) { + EditClassesByType.computeIfAbsent(ap.getDiffType(), d -> new ArrayList<>()).add(ap); } } - private ProposedElementaryPatterns() {} + private ProposedEditClasses() {} @Override - public List all() { + public List all() { return All; } @Override - public Map> byType() { - return PatternsByType; + public Map> byType() { + return EditClassesByType; } @Override - public ElementaryPattern match(DiffNode node) + public EditClass match(DiffNode node) { - // This is an inlined version of all patterns to optimize runtime when detecting the pattern of a certain node. + // This is an inlined version of all edit classes to optimize runtime when detecting the class of a certain node. // Because this compiles, we know that each branch terminates and returns a value. - // Each returned value is not null but an actual pattern object. - // Since the given node may be any node, we have proven that every node is classified by at least one pattern. + // Each returned value is not null but an actual edit class object. + // Since the given node may be any node, we have proven that every node is classified by at least one edit class. if (!node.isArtifact()) { throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!"); } @@ -133,11 +133,11 @@ public ElementaryPattern match(DiffNode node) } /** - * Returns the elementary edit pattern that has the given name. - * Returns empty of no pattern has the given name. + * Returns the edit class that has the given name. + * Returns empty of no edit class has the given name. */ - public Optional fromName(String label) { - for (final ElementaryPattern p : All) { + public Optional fromName(String label) { + for (final EditClass p : All) { if (p.getName().equals(label)) { return Optional.of(p); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Reconfiguration.java similarity index 72% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/Reconfiguration.java index b27a06e74..cbe7de735 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Reconfiguration.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Reconfiguration.java @@ -1,16 +1,16 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our Reconfiguration pattern from the ESEC/FSE'22 paper. + * Our Reconfiguration edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class Reconfiguration extends ElementaryPattern { +final class Reconfiguration extends EditClass { Reconfiguration() { super("Reconfiguration", DiffType.NON); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Refactoring.java similarity index 73% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/Refactoring.java index d2b337e2b..e2a2c82ca 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Refactoring.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Refactoring.java @@ -1,16 +1,16 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our Refactoring pattern from the ESEC/FSE'22 paper. + * Our Refactoring edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class Refactoring extends ElementaryPattern { +final class Refactoring extends EditClass { Refactoring() { super("Refactoring", DiffType.NON); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/RemFromPC.java similarity index 63% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/RemFromPC.java index 0139c4860..436684ccc 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemFromPC.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/RemFromPC.java @@ -1,14 +1,14 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our RemFromPC pattern from the ESEC/FSE'22 paper. + * Our RemFromPC edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class RemFromPC extends ElementaryPattern { +final class RemFromPC extends EditClass { RemFromPC() { super("RemFromPC", DiffType.REM); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/RemWithMapping.java similarity index 62% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/RemWithMapping.java index ec161f860..a527e7f9d 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/RemWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/RemWithMapping.java @@ -1,14 +1,14 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our RemWithMapping pattern from the ESEC/FSE'22 paper. + * Our RemWithMapping edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class RemWithMapping extends ElementaryPattern { +final class RemWithMapping extends EditClass { RemWithMapping() { super("RemWithMapping", DiffType.REM); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Specialization.java similarity index 72% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/Specialization.java index c6f4e5e86..0ef55ac55 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Specialization.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Specialization.java @@ -1,16 +1,16 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our Specialization pattern from the ESEC/FSE'22 paper. + * Our Specialization edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -final class Specialization extends ElementaryPattern { +final class Specialization extends EditClass { Specialization() { super("Specialization", DiffType.NON); } diff --git a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Untouched.java similarity index 73% rename from src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java rename to src/main/java/org/variantsync/diffdetective/editclass/proposed/Untouched.java index 615b7bf3b..488ab3fa8 100644 --- a/src/main/java/org/variantsync/diffdetective/pattern/proposed/Untouched.java +++ b/src/main/java/org/variantsync/diffdetective/editclass/proposed/Untouched.java @@ -1,16 +1,16 @@ -package org.variantsync.diffdetective.pattern.proposed; +package org.variantsync.diffdetective.editclass.proposed; import org.prop4j.Node; import org.variantsync.diffdetective.analysis.logic.SAT; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; /** - * Our Untouched pattern from the ESEC/FSE'22 paper. + * Our Untouched edit class from the ESEC/FSE'22 paper. * @author Paul Bittner, Sören Viegener */ -public class Untouched extends ElementaryPattern { +public class Untouched extends EditClass { Untouched() { super("Untouched", DiffType.NON); } diff --git a/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java b/src/main/java/org/variantsync/diffdetective/metadata/EditClassCount.java similarity index 58% rename from src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java rename to src/main/java/org/variantsync/diffdetective/metadata/EditClassCount.java index 111d17e58..b5ed6af61 100644 --- a/src/main/java/org/variantsync/diffdetective/metadata/ElementaryPatternCount.java +++ b/src/main/java/org/variantsync/diffdetective/metadata/EditClassCount.java @@ -1,9 +1,9 @@ package org.variantsync.diffdetective.metadata; import org.variantsync.diffdetective.diff.CommitDiff; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.ElementaryPatternCatalogue; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.EditClassCatalogue; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Assert; import org.variantsync.functjonal.Functjonal; import org.variantsync.functjonal.category.InplaceSemigroup; @@ -15,10 +15,10 @@ import java.util.stream.Collectors; /** - * Metadata that tracks how often elementary edit patterns were matched. + * Metadata that tracks how often edit classes were matched. * @author Paul Bittner */ -public class ElementaryPatternCount implements Metadata { +public class EditClassCount implements Metadata { /** * Counts the occurrences of a data point across commits. */ @@ -65,66 +65,67 @@ public String toString() { } /** - * Composes two pattern counts by composing their respective occurrence counts for elementary edit patterns. + * Composes two edit class counts by composing their respective occurrence counts for each edit + * class. * @see Occurrences#ISEMIGROUP */ - public static InplaceSemigroup ISEMIGROUP = (a, b) -> MergeMap.putAllValues( + public static InplaceSemigroup ISEMIGROUP = (a, b) -> MergeMap.putAllValues( a.occurences, b.occurences, Occurrences.ISEMIGROUP ); - private final LinkedHashMap occurences; + private final LinkedHashMap occurences; /** - * Create a new empty count with the {@link ProposedElementaryPatterns default pattern catalog}. + * Create a new empty count with the {@link ProposedEditClasses default edit class catalog}. */ - public ElementaryPatternCount() { - this(ProposedElementaryPatterns.Instance); + public EditClassCount() { + this(ProposedEditClasses.Instance); } /** - * Create a new empty count that reports occurrences of the given elementary edit patterns. - * @param patterns Patterns whose occurrences should be counted. + * Create a new empty count that reports occurrences of the given edit class. + * @param editClasses edit classes whose occurrences should be counted. */ - public ElementaryPatternCount(final ElementaryPatternCatalogue patterns) { + public EditClassCount(final EditClassCatalogue editClasses) { occurences = new LinkedHashMap<>(); - for (final ElementaryPattern p : patterns.all()) { + for (final EditClass p : editClasses.all()) { occurences.put(p, new Occurrences()); } } /** - * Report the match of the given pattern in the given commit diff. - * The count of the given pattern will be incremented and the commit will be memorized as - * one of the commits in which this elementary pattern was matched. - * @param pattern The pattern that was matched. - * @param commit The CommitDiff in which the pattern match occurred. - * @throws AssertionError when the given pattern is not a pattern of this counds catalog. - * @see #ElementaryPatternCount(ElementaryPatternCatalogue) + * Report the match of the given edit class in the given commit diff. + * The count of the given edit class will be incremented and the commit will be memorized as + * one of the commits in which this edit class was matched. + * @param editClass The edit class that was matched. + * @param commit The CommitDiff in which the edit class match occurred. + * @throws AssertionError when the given edit class is not present this counts catalog. + * @see #EditClassCount(EditClassCatalogue) */ - public void reportOccurrenceFor(final ElementaryPattern pattern, CommitDiff commit) { + public void reportOccurrenceFor(final EditClass editClass, CommitDiff commit) { Assert.assertTrue( - occurences.containsKey(pattern), - () -> "Reported unkown pattern \"" - + pattern.getName() + occurences.containsKey(editClass), + () -> "Reported unkown edit class \"" + + editClass.getName() + "\" but expected one of " + occurences.keySet().stream() - .map(ElementaryPattern::getName) + .map(EditClass::getName) .collect(Collectors.joining()) + "!" ); - occurences.get(pattern).increment(commit); + occurences.get(editClass).increment(commit); } /** - * Parses lines containing {@link ElementaryPattern elementary patterns} to {@link ElementaryPatternCount}. + * Parses lines containing {@link EditClass edit classes} to {@link EditClassCount}. * - * @param lines Lines containing {@link ElementaryPattern elementary patterns} to be parsed - * @return {@link ElementaryPatternCount} + * @param lines Lines containing {@link EditClass edit classes} to be parsed + * @return {@link EditClassCount} */ - public static ElementaryPatternCount parse(final List lines, final String uuid) { - ElementaryPatternCount count = new ElementaryPatternCount(); + public static EditClassCount parse(final List lines, final String uuid) { + EditClassCount count = new EditClassCount(); String[] keyValuePair; String key; String value; @@ -133,17 +134,17 @@ public static ElementaryPatternCount parse(final List lines, final Strin int commits; for (final String line : lines) { keyValuePair = line.split(": "); - key = keyValuePair[0]; // elementary pattern + key = keyValuePair[0]; // edit class value = keyValuePair[1]; // key value content value = value.replaceAll("[{} ]", ""); // remove unnecessary symbols innerKeyValuePair = value.split(";"); total = Integer.parseInt(innerKeyValuePair[0].split("=")[1]); // total count commits = Integer.parseInt(innerKeyValuePair[1].split("=")[1]); - // get pattern from key + // get edit class from key final String finalKey = key; - ElementaryPattern pattern = ProposedElementaryPatterns.Instance.fromName(key).orElseThrow( - () -> new RuntimeException("Could not find Elementary Pattern with name " + finalKey) + EditClass editClass = ProposedEditClasses.Instance.fromName(key).orElseThrow( + () -> new RuntimeException("Could not find EditClass with name " + finalKey) ); Occurrences occurence = new Occurrences(); @@ -155,7 +156,7 @@ public static ElementaryPatternCount parse(final List lines, final Strin } // add occurrence - count.occurences.put(pattern, occurence); + count.occurences.put(editClass, occurence); } return count; @@ -165,7 +166,7 @@ public static ElementaryPatternCount parse(final List lines, final Strin public LinkedHashMap snapshot() { return Functjonal.bimap( occurences, - ElementaryPattern::getName, + EditClass::getName, Occurrences::toString, LinkedHashMap::new ); @@ -175,14 +176,14 @@ public LinkedHashMap snapshot() { * Mutates and returns first element. */ @Override - public InplaceSemigroup semigroup() { + public InplaceSemigroup semigroup() { return ISEMIGROUP; } /** - * Returns the current occurrence count for each considered elementary edit pattern. + * Returns the current occurrence count for each considered edit class. */ - public LinkedHashMap getOccurences() { + public LinkedHashMap getOccurences() { return occurences; } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java index 971805981..d20f18267 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java +++ b/src/main/java/org/variantsync/diffdetective/mining/MiningTask.java @@ -11,8 +11,8 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.util.FileUtils; @@ -48,8 +48,8 @@ public AnalysisResult call() throws Exception { } /* - * We export all difftrees that match our filter criteria (e.g., has more than one elementary pattern). - * However, we count elementary patterns of all DiffTrees, even those that are not exported to Linegraph. + * We export all difftrees that match our filter criteria (e.g., match more than one edit class). + * However, we count edit classes of all DiffTrees, even those that are not exported to Linegraph. */ final CommitDiff commitDiff = commitDiffResult.diff().get(); final StringBuilder lineGraph = new StringBuilder(); @@ -57,10 +57,10 @@ public AnalysisResult call() throws Exception { options.analysisStrategy().onCommit(commitDiff, lineGraph.toString()); options.exportOptions().treeFilter().resetExplanations(); - // Count elementary patterns + // Count edit classes int numDiffTrees = 0; for (final PatchDiff patch : commitDiff.getPatchDiffs()) { - final PatchStatistics thisPatchesStatistics = new PatchStatistics(patch, ProposedElementaryPatterns.Instance); + final PatchStatistics thisPatchesStatistics = new PatchStatistics(patch, ProposedEditClasses.Instance); if (patch.isValid()) { final DiffTree t = patch.getDiffTree(); @@ -73,12 +73,12 @@ public AnalysisResult call() throws Exception { t.forAll(node -> { if (node.isArtifact()) { - final ElementaryPattern nodePattern = ProposedElementaryPatterns.Instance.match(node); - miningResult.elementaryPatternCounts.reportOccurrenceFor( - nodePattern, + final EditClass editClass = ProposedEditClasses.Instance.match(node); + miningResult.editClassCounts.reportOccurrenceFor( + editClass, commitDiff ); - thisPatchesStatistics.elementaryPatternCount().increment(nodePattern); + thisPatchesStatistics.editClassCount().increment(editClass); } }); diff --git a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java index f0d1f9831..05d8e8db3 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java @@ -2,13 +2,13 @@ import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.mining.formats.DebugMiningDiffNodeFormat; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; public class RWCompositePatternNodeFormat extends DebugMiningDiffNodeFormat { @Override public String toLabel(final DiffNode node) { if (node.isArtifact()) { - return ProposedElementaryPatterns.Instance.match(node).getName() + "
    " + node.getLabel(); + return ProposedEditClasses.Instance.match(node).getName() + "
    " + node.getLabel(); } else { return node.diffType + "_" + switch (node.nodeType) { case ROOT -> "r"; diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java index b6df74fa3..44eccfaf2 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java @@ -3,22 +3,22 @@ import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.functjonal.Pair; import java.util.Arrays; /** * Analogous to {@link ReleaseMiningDiffNodeFormat} but produces human readable labels instead of using integers. - * Artifact nodes are labeled with the name of their matched elementary pattern. + * Artifact nodes are labeled with the name of their matched edit class. * Annotation nodes are labeled with DIFFTYPE_NODETYPE (e.g., an added IF node gets the label ADD_IF). */ public class DebugMiningDiffNodeFormat implements MiningNodeFormat { @Override public String toLabel(final DiffNode node) { if (node.isArtifact()) { - return ProposedElementaryPatterns.Instance.match(node).getName(); + return ProposedEditClasses.Instance.match(node).getName(); } else if (node.isRoot()) { return node.diffType + "_" + NodeType.IF; } else { @@ -35,15 +35,15 @@ public Pair fromEncodedTypes(String tag) { final int nodeTypeBegin = tag.indexOf("_") + 1; final NodeType nt = NodeType.fromName(tag.substring(nodeTypeBegin)); if (nt == NodeType.ROOT) { - throw new IllegalArgumentException("There should be no roots in mined patterns!"); + throw new IllegalArgumentException("There should be no roots in mined edit classes!"); } return new Pair<>(dt, nt); } else { - final ElementaryPattern pattern = ProposedElementaryPatterns.Instance.fromName(tag).orElseThrow( - () -> new IllegalStateException("Label \"" + tag + "\" is neither an annotation label, nor an elementary pattern!") + final EditClass editClass = ProposedEditClasses.Instance.fromName(tag).orElseThrow( + () -> new IllegalStateException("Label \"" + tag + "\" is neither an annotation label, nor an edit class!") ); - return new Pair<>(pattern.getDiffType(), NodeType.ARTIFACT); + return new Pair<>(editClass.getDiffType(), NodeType.ARTIFACT); } } } diff --git a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java index 37d61d4f1..8737b4822 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java +++ b/src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java @@ -3,28 +3,28 @@ import org.variantsync.diffdetective.diff.difftree.NodeType; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffType; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Assert; import org.variantsync.functjonal.Pair; /** * Formats for DiffNodes for mining. * The label of a node starts with c (for code) if it is an artifact node and with m (for macro) otherwise. - * The label of artifact nodes is followed by the index of its matched elementary pattern. + * The label of artifact nodes is followed by the index of its matched edit class. * The label of diff nodes is followed by the ordinal of its diff type and the ordinal of its node type. * * Examples: - * DiffNode with nodeType=ARTIFACT and elementary pattern AddWithMapping gets the label "c1" because AddWithMapping has index 1. + * DiffNode with nodeType=ARTIFACT and edit class AddWithMapping gets the label "c1" because AddWithMapping has index 1. * DiffNode with nodeType=ELSE and difftype=REM gets the label "m23" because the ordinal or REM is 2 and the ordinal of ELSE is 3. */ public class ReleaseMiningDiffNodeFormat implements MiningNodeFormat { public final static String ARTIFACT_PREFIX = "c"; public final static String ANNOTATION_PREFIX = "m"; - private static int toId(final ElementaryPattern p) { - for (int i = 0; i < ProposedElementaryPatterns.All.size(); ++i) { - if (p.equals(ProposedElementaryPatterns.All.get(i))) { + private static int toId(final EditClass p) { + for (int i = 0; i < ProposedEditClasses.All.size(); ++i) { + if (p.equals(ProposedEditClasses.All.get(i))) { return i; } } @@ -32,14 +32,14 @@ private static int toId(final ElementaryPattern p) { throw new IllegalArgumentException("bug"); } - private static ElementaryPattern fromId(int id) { - return ProposedElementaryPatterns.All.get(id); + private static EditClass fromId(int id) { + return ProposedEditClasses.All.get(id); } @Override public String toLabel(DiffNode node) { if (node.isArtifact()) { - return ARTIFACT_PREFIX + toId(ProposedElementaryPatterns.Instance.match(node)); + return ARTIFACT_PREFIX + toId(ProposedEditClasses.Instance.match(node)); } else { final NodeType nodeType = node.isRoot() ? NodeType.IF : node.nodeType; return ANNOTATION_PREFIX + node.diffType.ordinal() + nodeType.ordinal(); @@ -49,8 +49,8 @@ public String toLabel(DiffNode node) { @Override public Pair fromEncodedTypes(String tag) { if (tag.startsWith(ARTIFACT_PREFIX)) { - final ElementaryPattern pattern = fromId(Integer.parseInt(tag.substring(ARTIFACT_PREFIX.length()))); - return new Pair<>(pattern.getDiffType(), NodeType.ARTIFACT); + final EditClass editClass = fromId(Integer.parseInt(tag.substring(ARTIFACT_PREFIX.length()))); + return new Pair<>(editClass.getDiffType(), NodeType.ARTIFACT); } else { Assert.assertTrue(tag.startsWith(ANNOTATION_PREFIX)); final int diffTypeBegin = ANNOTATION_PREFIX.length(); @@ -62,7 +62,7 @@ public Pair fromEncodedTypes(String tag) { tag.substring(nodeTypeBegin, nodeTypeBegin + 1) )]; if (nodeType == NodeType.ROOT) { - throw new IllegalArgumentException("There should be no roots in mined patterns!"); + throw new IllegalArgumentException("There should be no roots in mined edit classes!"); } return new Pair<>(diffType, nodeType); } diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java index 8664f98da..7549f240c 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/MiningPostprocessing.java @@ -21,7 +21,7 @@ import java.util.stream.Collectors; /** - * Performs a postprocessing on mined frequent subgraphs in edits to find semantic edit patterns. + * Performs a postprocessing on mined frequent subgraphs in edits to find edit classes. */ public class MiningPostprocessing { private static final DiffTreeRenderer DefaultRenderer = DiffTreeRenderer.WithinDiffDetective(); diff --git a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java index 395a6836a..be79af63a 100644 --- a/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java +++ b/src/main/java/org/variantsync/diffdetective/mining/postprocessing/Postprocessor.java @@ -39,7 +39,7 @@ private Postprocessor( * Creates the default filter to distill semantic patterns from frequent subgraphs. * This processor will * - filter ill-formed trees - * - filter trees with less than two elementary patterns + * - filter trees with less than two edit classes * - filter duplicates w.r.t. isomorphism * - {@link CutNonEditedSubtrees} * @return the default postprocessor. @@ -50,7 +50,6 @@ public static Postprocessor Default() { List.of( // Filter ill-formed patterns DiffTreeFilter.consistent(), - // filter patterns containing less than two elementary patterns DiffTreeFilter.moreThanOneArtifactNode(), DiffTreeFilter.hasAtLeastOneEditToVariability() ) diff --git a/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java b/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java deleted file mode 100644 index 205a21e03..000000000 --- a/src/main/java/org/variantsync/diffdetective/pattern/ElementaryPatternCatalogue.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.variantsync.diffdetective.pattern; - -import org.variantsync.diffdetective.diff.difftree.DiffNode; -import org.variantsync.diffdetective.diff.difftree.DiffType; - -import java.util.List; -import java.util.Map; - -/** - * Interface for custom catalogs of elementary edit patterns. - * @author Paul Bittner - */ -public interface ElementaryPatternCatalogue { - /** - * Gives a list of all elementary patterns in this catalogue. - * The list should be constant and immutable (i.e., the very same list is returned each time all is invoked). - * The elementary patterns should be immutable, too. - * @return a constant list of all elementary patterns in this catalogue. - */ - List all(); - - /** - * Returns a mapping from diff types to the elementary patterns that may match nodes of the given diff type. - * The returned map as well as all its values should be immutable and constant. * - * @return A classification of elementary patterns by their diff types. - */ - Map> byType(); - - /** - * Returns the elementary pattern that matches the given node. - * Each node matches exactly one pattern. - * @param node The node of which to find its elementary pattern. - * @return Returns the elementary pattern that matches the given node. - */ - default ElementaryPattern match(DiffNode node) - { - if (!node.isArtifact()) { - throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!"); - } - - final List patternsToCheck = byType().get(node.diffType); - - ElementaryPattern match = null; - for (final ElementaryPattern p : patternsToCheck) { - if (p.matches(node)) { - if (match != null) { - throw new RuntimeException("BUG: Error in elementary pattern definition!\n" - + "Node " + node + " matched " + match + " and " + p + "!"); - } - match = p; - } - } - - if (match == null) { - throw new RuntimeException("BUG: Error in elementary pattern definition!\n" - + "Node " + node + " did not match any pattern!"); - } - - return match; - } -} diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java index 2e00e1ba0..0a519cb77 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/TreeGDAnalyzer.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.PatchDiff; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.ElementaryPattern; +import org.variantsync.diffdetective.editclass.EditClass; import org.variantsync.diffdetective.preliminary.GitDiff; import org.variantsync.diffdetective.preliminary.analysis.data.PatchDiffAnalysisResult; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; @@ -69,7 +69,7 @@ protected PatchDiffAnalysisResult analyzePatch(PatchDiff patchDiff) { // match atomic patterns for (DiffNode diffNode : diffTree.computeArtifactNodes()) { for (FeatureContextReverseEngineering pattern : patterns) { - if (pattern.getPattern() instanceof ElementaryPattern) { + if (pattern.getPattern() instanceof EditClass) { results.add(pattern.createMatch(diffNode)); // pattern.match(diffNode).ifPresent(results::add); } diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java index 074f0bd14..d88b2a11b 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddToPC.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -13,7 +13,7 @@ public final class FeatureContextOfAddToPC implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.AddToPC; + return ProposedEditClasses.AddToPC; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java index 65fbbb3ea..883ec9177 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfAddWithMapping.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -13,7 +13,7 @@ public final class FeatureContextOfAddWithMapping implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.AddWithMapping; + return ProposedEditClasses.AddWithMapping; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java index bceb3beb8..b5dade470 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfGeneralization.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ public final class FeatureContextOfGeneralization implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.Generalization; + return ProposedEditClasses.Generalization; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java index f75ab25cf..5feebca18 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfReconfiguration.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ public final class FeatureContextOfReconfiguration implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.Reconfiguration; + return ProposedEditClasses.Reconfiguration; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java index d277da625..64bb2bec7 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRefactoring.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ public final class FeatureContextOfRefactoring implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.Refactoring; + return ProposedEditClasses.Refactoring; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java index 8888e352c..d8ab176fe 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemFromPC.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -13,7 +13,7 @@ public final class FeatureContextOfRemFromPC implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.RemFromPC; + return ProposedEditClasses.RemFromPC; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java index 067a84074..af21ac27e 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfRemWithMapping.java @@ -4,7 +4,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -13,7 +13,7 @@ public final class FeatureContextOfRemWithMapping implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.RemWithMapping; + return ProposedEditClasses.RemWithMapping; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java index d2357aa5a..527f92b21 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfSpecialization.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ public final class FeatureContextOfSpecialization implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.Specialization; + return ProposedEditClasses.Specialization; } @Override diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java index f4be6595d..191d6dbe0 100644 --- a/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java +++ b/src/main/java/org/variantsync/diffdetective/preliminary/pattern/elementary/FeatureContextOfUntouched.java @@ -3,7 +3,7 @@ import org.variantsync.diffdetective.diff.Lines; import org.variantsync.diffdetective.diff.difftree.DiffNode; import org.variantsync.diffdetective.preliminary.pattern.Pattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch; import org.variantsync.diffdetective.preliminary.evaluation.FeatureContext; import org.variantsync.diffdetective.preliminary.pattern.FeatureContextReverseEngineering; @@ -12,7 +12,7 @@ public class FeatureContextOfUntouched implements FeatureContextReverseEngineering { @Override public Pattern getPattern() { - return ProposedElementaryPatterns.Untouched; + return ProposedEditClasses.Untouched; } @Override @@ -27,4 +27,4 @@ public PatternMatch createMatch(DiffNode codeNode) { public FeatureContext[] getFeatureContexts(PatternMatch patternMatch) { return new FeatureContext[0]; } -} +} \ No newline at end of file diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java b/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java index 45d7d2a37..1012d9e80 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/MiningResultAccumulator.java @@ -93,8 +93,8 @@ public static AnalysisResult computeTotalMetadataResult(final Collection *
  • Whether the results are filtered to only include the biggest datasets. *
  • Whether the amount of each edit type is given in absolute or relative numbers. - *
  • Whether the edit count of each pattern or only the share of edit pattern editing the - * variability is included. + *
  • Whether the edit count of each edit class or only the share of edit classes editing + * the variability is included. * * * @see getAllTotalResultsIn diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java index 55484c8c4..b235094e9 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java @@ -1,9 +1,9 @@ package org.variantsync.diffdetective.tablegen.styles; import org.apache.commons.lang3.function.TriFunction; -import org.variantsync.diffdetective.metadata.ElementaryPatternCount; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.metadata.EditClassCount; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.tablegen.ColumnDefinition; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; @@ -25,7 +25,7 @@ *
  • commit counts *
  • diff counts *
  • the number of artifact nodes - *
  • elementary pattern counts, either absolute or relative to the total count of all patterns + *
  • edit class counts, either absolute or relative to the total count of all edit classes *
  • processing time * * @@ -43,7 +43,7 @@ private ShortTable(boolean filtered) { } /** - * Constructs a table template with absolute pattern counts. + * Constructs a table template with absolute edit class counts. * * @param filtered if {@code true}, the rows will be filtered to only contain the biggest * datasets @@ -55,7 +55,7 @@ public static ShortTable Absolute(boolean filtered) { } /** - * Constructs a table template with relative pattern counts. + * Constructs a table template with relative edit class counts. * * @param filtered if {@code true}, the rows will be filtered to only contain the biggest * datasets @@ -70,9 +70,9 @@ public static ShortTable Relative(boolean filtered) { * Returns a list of all columns contained in this table. * * @param t instance to this class, used for formatting with {@link makeReadable} - * @param getPatternCount function to extract the pattern count of a row + * @param getEditClassCount function to extract the edit class count of a row */ - private static List columns(final ShortTable t, final TriFunction getPatternCount) { + private static List columns(final ShortTable t, final TriFunction getEditClassCount) { final List cols = new ArrayList<>(List.of( col("Name", LEFT, row -> row.dataset().name().toLowerCase(Locale.US)), col("Domain", LEFT_DASH, row -> row.dataset().domain()), @@ -81,17 +81,17 @@ private static List columns(final ShortTable t, final TriFunct col("\\#diffs", RIGHT, row -> t.makeReadable(row.results().exportedTrees)), col("\\#artifact nodes", RIGHT_DASH, row -> t.makeReadable(row .results() - .elementaryPatternCounts + .editClassCounts .getOccurences() .values().stream() - .map(ElementaryPatternCount.Occurrences::getTotalAmount) + .map(EditClassCount.Occurrences::getTotalAmount) .reduce(0, Integer::sum) )) )); - for (final ElementaryPattern a : ProposedElementaryPatterns.Instance.all()) { - if (a != ProposedElementaryPatterns.Untouched) { - cols.add(col(a.getName(), RIGHT, row -> getPatternCount.apply(t, a, row))); + for (final EditClass a : ProposedEditClasses.Instance.all()) { + if (a != ProposedEditClasses.Untouched) { + cols.add(col(a.getName(), RIGHT, row -> getEditClassCount.apply(t, a, row))); } } @@ -103,39 +103,39 @@ private static List columns(final ShortTable t, final TriFunct } /** - * Returns a formatted string of the absolute number of occurrences of {@code pattern} in + * Returns a formatted string of the absolute number of occurrences of {@code editClass} in * {@code row}. * The signature of this method is suitable to be passed to {@link column}. * * @param t an instance of this class contained in the column definition - * @param pattern the pattern to count - * @param row the data to count {@code pattern} in + * @param editClass the edit class to count + * @param row the data to count {@code editClass} in * @see column */ - private static String absoluteCountOf(final ShortTable t, final ElementaryPattern pattern, final ContentRow row) { - return t.makeReadable(row.results().elementaryPatternCounts.getOccurences().get(pattern).getTotalAmount()); + private static String absoluteCountOf(final ShortTable t, final EditClass editClass, final ContentRow row) { + return t.makeReadable(row.results().editClassCounts.getOccurences().get(editClass).getTotalAmount()); } /** - * Returns a formatted string of the relative number of occurrences of {@code pattern} in + * Returns a formatted string of the relative number of occurrences of {@code editClass} in * {@code row}. * The signature of this method is suitable to be passed to {@link column}. * * @param t an instance of this class contained in the column definition - * @param pattern the pattern to count - * @param row the data to count {@code pattern} in + * @param editClass the edit class to count + * @param row the data to count {@code editClass} in * @see column */ - private static String relativeCountOf(final ShortTable t, final ElementaryPattern pattern, final ContentRow row) { - final LinkedHashMap patternOccurrences = - row.results().elementaryPatternCounts.getOccurences(); + private static String relativeCountOf(final ShortTable t, final EditClass editClass, final ContentRow row) { + final LinkedHashMap editClassOccurrences = + row.results().editClassCounts.getOccurences(); int numTotalMatches = 0; - for (final Map.Entry occurrence : patternOccurrences.entrySet()) { + for (final Map.Entry occurrence : editClassOccurrences.entrySet()) { numTotalMatches += occurrence.getValue().getTotalAmount(); } - return t.makeReadable(100.0 * ((double) patternOccurrences.get(pattern).getTotalAmount()) / ((double) numTotalMatches)) + "\\%"; + return t.makeReadable(100.0 * ((double) editClassOccurrences.get(editClass).getTotalAmount()) / ((double) numTotalMatches)) + "\\%"; } /** diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java index e2925abb1..fa502418b 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/Table1.java @@ -1,7 +1,7 @@ package org.variantsync.diffdetective.tablegen.styles; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; import org.variantsync.diffdetective.tablegen.TableGenerator; @@ -21,7 +21,7 @@ *
  • a dataset description *
  • commit counts *
  • diff counts - *
  • elementary pattern counts + *
  • edit class counts *
  • processing time * */ @@ -37,8 +37,8 @@ public Table1() { col("\\#diffs", RIGHT, row -> makeReadable(row.results().exportedTrees)) )); - for (final ElementaryPattern a : ProposedElementaryPatterns.Instance.all()) { - this.columnDefinitions.add(col(a.getName(), RIGHT, row -> makeReadable(row.results().elementaryPatternCounts.getOccurences().get(a).getTotalAmount()))); + for (final EditClass a : ProposedEditClasses.Instance.all()) { + this.columnDefinitions.add(col(a.getName(), RIGHT, row -> makeReadable(row.results().editClassCounts.getOccurences().get(a).getTotalAmount()))); } this.columnDefinitions.add(col("runtime (s)", RIGHT, row -> makeReadable(row.results().runtimeInSeconds))); diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java index f4abbff3e..4b0471401 100644 --- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java +++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/VariabilityShare.java @@ -1,8 +1,8 @@ package org.variantsync.diffdetective.tablegen.styles; -import org.variantsync.diffdetective.metadata.ElementaryPatternCount; -import org.variantsync.diffdetective.pattern.ElementaryPattern; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.metadata.EditClassCount; +import org.variantsync.diffdetective.editclass.EditClass; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.tablegen.Row; import org.variantsync.diffdetective.tablegen.TableDefinition; import org.variantsync.diffdetective.tablegen.rows.ContentRow; @@ -22,7 +22,7 @@ *
      *
    • the name of the dataset *
    • the total number of edits to variability - *
    • a relative occurrence count for each pattern changing variability + *
    • a relative occurrence count for each edit class changing variability *
    */ public class VariabilityShare extends TableDefinition { @@ -38,38 +38,38 @@ public VariabilityShare(final Supplier inner) { col("\\#edits to\\\\ variability", RIGHT_DASH, row -> makeReadable(countEditsToVariability(row))) )); - for (final ElementaryPattern a : ProposedElementaryPatterns.Instance.all()) { + for (final EditClass a : ProposedEditClasses.Instance.all()) { if (isEditToVariability(a)) { this.columnDefinitions.add(col(a.getName(), RIGHT, row -> getRelativeShareOf(a, row))); } } } - /** Returns if the pattern {@code p} should be present in this table. */ - private static boolean isEditToVariability(final ElementaryPattern p) { - return p != ProposedElementaryPatterns.Untouched && p != ProposedElementaryPatterns.AddToPC && p != ProposedElementaryPatterns.RemFromPC; + /** Returns if the edit class {@code c} should be present in this table. */ + private static boolean isEditToVariability(final EditClass c) { + return c != ProposedEditClasses.Untouched && c != ProposedEditClasses.AddToPC && c != ProposedEditClasses.RemFromPC; } - /** Returns the number of occurrences of patterns present in the table. */ - private static Stream> getVariationalPatterns(final ContentRow row) { - return row.results().elementaryPatternCounts.getOccurences().entrySet().stream() + /** Returns the number of occurrences of edit classes present in the table. */ + private static Stream> getVariationalEditClasses(final ContentRow row) { + return row.results().editClassCounts.getOccurences().entrySet().stream() .filter(entry -> isEditToVariability(entry.getKey())); } - /** Compute the total sum of all occurrences of patterns present in this table. */ + /** Compute the total sum of all occurrences of edit classes present in this table. */ private static int countEditsToVariability(final ContentRow row) { - return getVariationalPatterns(row) + return getVariationalEditClasses(row) .map(entry -> entry.getValue().getTotalAmount()) .reduce(0, Integer::sum); } /** - * Compute the number of occurrences of {@code pattern} relative to the patterns actually + * Compute the number of occurrences of {@code editClass} relative to the edit classes actually * present in this table. */ - private String getRelativeShareOf(final ElementaryPattern pattern, final ContentRow row) { + private String getRelativeShareOf(final EditClass editClass, final ContentRow row) { final int totalAmount = countEditsToVariability(row); - return makeReadable(100.0 * ((double)row.results().elementaryPatternCounts.getOccurences().get(pattern).getTotalAmount()) / ((double) totalAmount)) + "\\%"; + return makeReadable(100.0 * ((double)row.results().editClassCounts.getOccurences().get(editClass).getTotalAmount()) / ((double) totalAmount)) + "\\%"; } /** diff --git a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java similarity index 92% rename from src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java rename to src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java index fd3392914..38ce99370 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/PatternValidationTask.java +++ b/src/main/java/org/variantsync/diffdetective/validation/EditClassValidationTask.java @@ -13,7 +13,7 @@ import org.variantsync.diffdetective.diff.difftree.transform.DiffTreeTransformer; import org.variantsync.diffdetective.diff.result.CommitDiffResult; import org.variantsync.diffdetective.metadata.ExplainedFilterSummary; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.util.FileUtils; @@ -24,8 +24,8 @@ * Task for performing the ESEC/FSE'22 validation on a set of commits from a given repository. * @author Paul Bittner */ -public class PatternValidationTask extends CommitHistoryAnalysisTask { - public PatternValidationTask(Options options) { +public class EditClassValidationTask extends CommitHistoryAnalysisTask { + public EditClassValidationTask(Options options) { super(options); } @@ -61,7 +61,7 @@ public AnalysisResult call() throws Exception { final CommitDiff commitDiff = commitDiffResult.diff().get(); options.analysisStrategy().onCommit(commitDiff, ""); - // Count elementary edit pattern matches + // Count edit class matches int numDiffTrees = 0; for (final PatchDiff patch : commitDiff.getPatchDiffs()) { if (patch.isValid()) { @@ -75,8 +75,8 @@ public AnalysisResult call() throws Exception { t.forAll(node -> { if (node.isArtifact()) { - miningResult.elementaryPatternCounts.reportOccurrenceFor( - ProposedElementaryPatterns.Instance.match(node), + miningResult.editClassCounts.reportOccurrenceFor( + ProposedEditClasses.Instance.match(node), commitDiff ); } diff --git a/src/main/java/org/variantsync/diffdetective/validation/Validation.java b/src/main/java/org/variantsync/diffdetective/validation/Validation.java index 1196bd501..431ac5aa4 100644 --- a/src/main/java/org/variantsync/diffdetective/validation/Validation.java +++ b/src/main/java/org/variantsync/diffdetective/validation/Validation.java @@ -49,10 +49,10 @@ public class Validation { /** * The {@link CommitHistoryAnalysisTaskFactory} for the {@link HistoryAnalysis} that will run our validation. - * This factory creates {@link PatternValidationTask}s with the respective settings. + * This factory creates {@link EditClassValidationTask}s with the respective settings. */ public static final CommitHistoryAnalysisTaskFactory VALIDATION_TASK_FACTORY = - (repo, differ, outputPath, commits) -> new PatternValidationTask(new CommitHistoryAnalysisTask.Options( + (repo, differ, outputPath, commits) -> new EditClassValidationTask(new CommitHistoryAnalysisTask.Options( repo, differ, outputPath, diff --git a/src/test/java/ElementaryPatternsTest.java b/src/test/java/EditClassesTest.java similarity index 76% rename from src/test/java/ElementaryPatternsTest.java rename to src/test/java/EditClassesTest.java index 5e05997ae..4ec3adc13 100644 --- a/src/test/java/ElementaryPatternsTest.java +++ b/src/test/java/EditClassesTest.java @@ -1,12 +1,12 @@ import org.junit.Assert; import org.junit.Test; import org.variantsync.diffdetective.diff.difftree.DiffTree; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import java.io.IOException; import java.nio.file.Path; -public class ElementaryPatternsTest { +public class EditClassesTest { private final static Path testDir = Constants.RESOURCE_DIR.resolve("patterns"); @Test @@ -17,7 +17,7 @@ public void testAtomics() throws IOException { if (node.isArtifact()) { Assert.assertEquals( node.getLabel(), - ProposedElementaryPatterns.Instance.match(node).getName() + ProposedEditClasses.Instance.match(node).getName() ); } }); diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java index e2acbc02f..b2d0e4340 100644 --- a/src/test/java/MarlinDebug.java +++ b/src/test/java/MarlinDebug.java @@ -23,7 +23,7 @@ import org.variantsync.diffdetective.feature.CPPAnnotationParser; import org.variantsync.diffdetective.mining.DiffTreeMiner; import org.variantsync.diffdetective.mining.MiningTask; -import org.variantsync.diffdetective.pattern.proposed.ProposedElementaryPatterns; +import org.variantsync.diffdetective.editclass.proposed.ProposedEditClasses; import org.variantsync.diffdetective.util.Clock; import org.variantsync.diffdetective.validation.Validation; @@ -104,7 +104,7 @@ public static void testCommit(final RepoInspection repoInspection, final String t.forAll(node -> { if (node.isArtifact()) { try { - Logger.info(ProposedElementaryPatterns.Instance.match(node)); + Logger.info(ProposedEditClasses.Instance.match(node)); } catch (Exception e) { //DiffTreeLineGraphExportOptions.RenderError().accept(patch, e); Logger.error(e); From a51723f3059523fdfa6edab23df9b08074405f2e Mon Sep 17 00:00:00 2001 From: Benjamin Moosherr Date: Sat, 17 Sep 2022 12:14:35 +0200 Subject: [PATCH 15/19] Rename CollapseEditClasses to LabelWithEditClass I think the meaningfulness of this rename is best explained by the second sentence of the original class description: > Contrary to its name, [...] --- ...{CollapseEditClasses.java => LabelWithEditClass.java} | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) rename src/main/java/org/variantsync/diffdetective/diff/difftree/transform/{CollapseEditClasses.java => LabelWithEditClass.java} (78%) diff --git a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/LabelWithEditClass.java similarity index 78% rename from src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java rename to src/main/java/org/variantsync/diffdetective/diff/difftree/transform/LabelWithEditClass.java index e96a19c67..d64a5fa55 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/CollapseEditClasses.java +++ b/src/main/java/org/variantsync/diffdetective/diff/difftree/transform/LabelWithEditClass.java @@ -7,14 +7,13 @@ import java.util.List; /** - * Collapses edit classes in a DiffTree. - * Contrary to its name, this transformation leaves a DiffTree's graph structure unchanged. - * This transformation uses the {@link RelabelNodes} transformer to relabel all nodes. + * Label all nodes with their edit class. + * This transformation leaves the graph structure of the {@link DiffTree} unchanged. * All {@link DiffNode#isArtifact() artifact} nodes will be labeled by their respective edit class. * All other nodes will be labeled by the {@link org.variantsync.diffdetective.diff.difftree.NodeType#name name of their node type}. * @author Paul Bittner */ -public class CollapseEditClasses implements DiffTreeTransformer { +public class LabelWithEditClass implements DiffTreeTransformer { private final DiffTreeTransformer relabelNodes; /** @@ -22,7 +21,7 @@ public class CollapseEditClasses implements DiffTreeTransformer { * to relabel {@link DiffNode#isArtifact() artifact} nodes. * @param editClasses Catalog of edit classes to match on artifact nodes. */ - public CollapseEditClasses(final EditClassCatalogue editClasses) { + public LabelWithEditClass(final EditClassCatalogue editClasses) { relabelNodes = new RelabelNodes(d -> { if (d.isArtifact()) { return editClasses.match(d).getName(); From 7f858781416084cf609fe5b7892374b6b1a80712 Mon Sep 17 00:00:00 2001 From: Paul Maximilian Bittner Date: Sat, 24 Sep 2022 11:32:11 +0200 Subject: [PATCH 16/19] fix: test does not crash on win anymore if dot is missing --- src/test/java/ExportTest.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test/java/ExportTest.java b/src/test/java/ExportTest.java index 39c93f8bf..20fbebd96 100644 --- a/src/test/java/ExportTest.java +++ b/src/test/java/ExportTest.java @@ -1,4 +1,5 @@ import org.junit.Test; +import org.tinylog.Logger; import org.variantsync.diffdetective.diff.difftree.DiffTree; import org.variantsync.diffdetective.diff.difftree.serialize.*; import org.variantsync.diffdetective.diff.difftree.serialize.edgeformat.DefaultEdgeLabelFormat; @@ -45,8 +46,16 @@ public void export() throws IOException { // Export the test case var tikzOutput = new ByteArrayOutputStream(); - new TikzExporter(format).exportDiffTree(diffTree, tikzOutput); - TestUtils.assertEqualToFile(Path.of("src/test/resources/serialize/expected.tex"), tikzOutput.toString()); + try { + new TikzExporter(format).exportDiffTree(diffTree, tikzOutput); + TestUtils.assertEqualToFile(Path.of("src/test/resources/serialize/expected.tex"), tikzOutput.toString()); + } catch (IOException e) { + if (e.getMessage().contains("Cannot run program")) { + Logger.warn("Missing programs! Did you install graphviz? Reason: " + e.getMessage()); + } else { + throw e; + } + } } } From 49767ce9b2879155337b2d1ee08fb1a102b5502a Mon Sep 17 00:00:00 2001 From: Paul Maximilian Bittner Date: Sat, 24 Sep 2022 11:55:13 +0200 Subject: [PATCH 17/19] docs: added testes OS from reviews --- REQUIREMENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index bc0d49ba2..663612901 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -5,7 +5,7 @@ None ## Software Requirements We do not require a certain operating system or prepared environment. -We tested our setup on Windows 10, WSL2, and Manjaro. +The setup is tested on Windows 10, WSL2, Manjaro, Ubuntu, and MacOS Monterey. To run DiffDetective, JDK16, and Maven are required. Dependencies to other packages are documented in the maven build file ([pom.xml](pom.xml)) and are handled automatically by Maven. From 154bfa60e62566743c07aac19d5eba4d2441f29a Mon Sep 17 00:00:00 2001 From: Paul Maximilian Bittner Date: Sat, 24 Sep 2022 11:55:25 +0200 Subject: [PATCH 18/19] docs: fixed name inconsistencies --- README.md | 4 ++-- STATUS.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 60fbcb635..d2547858b 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Moreover, the results comprise the (LaTeX) tables that are part of our paper and DiffDetective is documented with javadoc. The documentation can be accessed on this [website][documentation]. Notable classes of our library are: - [DiffTree](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/diff/difftree/DiffTree.html) and [DiffNode](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/diff/difftree/DiffNode.html) implement variation diffs from our paper. A variation diff is represented by an instance of the `DiffTree` class. It stores the root node of the diff and offers various methods to parse, traverse, and analyze variation diffs. `DiffNode`s represent individual nodes within a variation diff. - [Validation](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/validation/Validation.html) contains the main method for our validation. -- [ProposedElementaryPatterns](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/pattern/elementary/proposed/ProposedElementaryPatterns.html) holds the catalog of the nine edit classes we proposed in our paper. It implements the interface [ElementaryPatternCatalogue](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/pattern/elementary/ElementaryPatternCatalogue.html), which allows to define custom edit classifications. +- [ProposedEditClasses](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/editclass/proposed/ProposedEditClasses.html) holds the catalog of the nine edit classes we proposed in our paper. It implements the interface [EditClassCatalogue](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/editclass/EditClassCatalogue.html), which allows to define custom edit classifications. - [BooleanAbstraction](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/feature/BooleanAbstraction.html) contains data and methods for boolean abstraction of higher-order logic formulas. We use this for macro parsing. - [GitDiffer](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/diff/GitDiffer.html) may parse the history of a git repository to variation diffs. - The [datasets](https://variantsync.github.io/DiffDetective/docs/javadoc/org/variantsync/diffdetective/datasets/package-summary.html) package contains various classes for describing and loading datasets. @@ -95,7 +95,7 @@ How to build our library and how to run the example is described in the [proofs/ ## 4. Dataset Overview ### 4.1 Open-Source Repositories We provide an overview of the used 44 open-source preprocessor-based software product lines in the [docs/datasets.md][dataset] file. -As described in our paper in Section 5.1 this list contains all systems that were studied by Liebig et al., extended by four new subject systems (Busybox, Marlin, LibSSH, Godot). +As described in our paper in Section 5.1, this list contains all systems that were studied by Liebig et al., extended by four new subject systems (Busybox, Marlin, LibSSH, Godot). We provide updated links for each system's repository. ### 4.2 Forked Repositories for Replication diff --git a/STATUS.md b/STATUS.md index 57f576ce0..10c908018 100644 --- a/STATUS.md +++ b/STATUS.md @@ -3,7 +3,7 @@ The artifact for the paper _Classifying Edits to Variability in Source Code_ consists of four parts: 1. **DiffDetective**: For our validation, we built DiffDetective, a java library and command-line tool to classify edits to variability in git histories of preprocessor-based software product lines. - DiffDetective is the main artifact used to replicate the validation for our paper (see Section 5). + DiffDetective is the main artifact used to replicate the validation of our paper (see Section 5). DiffDetective is self-contained in that it does not require or depend on in-depth knowledge on the theoretical foundation of our work. Practitioners and researches are free to ignore the appendix as well as the haskell formalization and may use DiffDetective out-of-the-box. 2. **Appendix**: The appendix of our paper is given in PDF format in the file [`appendix.pdf`][ddappendix]. @@ -22,14 +22,14 @@ DiffDetective is designed as a library that offers reusable functionality. Researchers and practitioners can use our DiffDetective library to build on our theory and results (e.g., for future prototypes to study the evolution of variability in source code). DiffDetective offers various features, including but not limited to: -parsing variation tree diffs from unix diffs, obtaining variation tree diffs for certain patches and commits, matching elementary edit patterns on variation tree diffs, defining custom classifications, rendering, traversing, and transforming variation tree diffs, various de-/serialization methods, and running analyses for the git histories of C preprocessor-based software product lines. We documented each part of the library and provide a [javadoc website][dddocumentation] within the repository. +parsing variation diffs from unix diffs, obtaining variation diffs for certain patches and commits, classifying edits in variation diffs, defining custom classifications, rendering, traversing, and transforming variation diffs, various de-/serialization methods, and running analyses for the git histories of C preprocessor-based software product lines. We documented each part of the library and provide a [javadoc website][dddocumentation] within the repository. Moreover, our validation (see _replicability_ above) may also be run on any custom dataset as described in our [README.md][ddreadme]. ### **Extended Formal Specification** The [`proofs`][ddproofs] Haskell project provides an extended formal specification of our theory. Its main purpose is to document the theory and its extensions to serve as a reference for the proofs in our appendix. Yet, the project can also be used as a library to reason on variation trees and diffs in Haskell projects. -The library is accompanied by a small demo application that shows an example test case for our proof of completeness by creating a variation tree diff from two variation trees and re-projecting them. +The library is accompanied by a small demo application that shows an example test case for our proof of completeness by creating a variation diff from two variation trees and re-projecting them. The `proofs` project is described in detail in our appendix. ## Claims From 56f385ab3a8674c9ef7bd3636f85d5b297853b13 Mon Sep 17 00:00:00 2001 From: Paul Maximilian Bittner Date: Sat, 24 Sep 2022 12:00:37 +0200 Subject: [PATCH 19/19] docs: styling improvement in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2547858b..94da0a7b9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -# Classifying Edits to Variability in Source Code - ACM Artifacts Evaluated Reusable ![Maven](https://github.com/VariantSync/DiffDetective/actions/workflows/maven.yml/badge.svg) @@ -10,6 +8,8 @@ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6818140.svg)](https://doi.org/10.5281/zenodo.6818140) [![Status](https://img.shields.io/badge/ESEC%2FFSE'22-Badge%20Application-blue)](STATUS.md) +# Classifying Edits to Variability in Source Code + This is the replication package for our paper _Classifying Edits to Variability in Source Code_ accepted at the 30th ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE 2022). This replication package consists of four parts: