Skip to content

Commit 1d227f5

Browse files
committed
fix: EliminateEmptyAlt. making inconsistent labels
1 parent 75be10f commit 1d227f5

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

src/main/java/org/variantsync/diffdetective/variation/diff/transform/EliminateEmptyAlternatives.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
21
package org.variantsync.diffdetective.variation.diff.transform;
32

43
import org.prop4j.Node;
5-
import org.variantsync.diffdetective.variation.Label;
4+
import org.prop4j.NodeWriter;
5+
import org.variantsync.diffdetective.util.Assert;
6+
import org.variantsync.diffdetective.util.StringUtils;
7+
import org.variantsync.diffdetective.variation.DiffLinesLabel;
8+
import static org.variantsync.diffdetective.variation.DiffLinesLabel.Line;
69
import org.variantsync.diffdetective.variation.tree.VariationTree;
710
import org.variantsync.diffdetective.variation.tree.VariationTreeNode;
811

@@ -35,20 +38,52 @@
3538
*
3639
* @author Paul Bittner
3740
*/
38-
public class EliminateEmptyAlternatives<L extends Label> implements Transformer<VariationTree<L>> {
39-
private void elim(VariationTreeNode<L> subtree) {
41+
public class EliminateEmptyAlternatives implements Transformer<VariationTree<DiffLinesLabel>> {
42+
/**
43+
* Creates a copy of the given label but where the formula is set to the given formula.
44+
* This method also updates the text in the DiffLinesLabel accordingly so that the text is
45+
* consistent with the formula.
46+
* This method assumes that the label has at least one line of text, otherwise the given label
47+
* could not have a formula.
48+
*/
49+
private static DiffLinesLabel updatedLabel(DiffLinesLabel l, Node formula) {
50+
final List<Line> lines = l.getDiffLines();
51+
Assert.assertFalse(lines.isEmpty());
52+
53+
// Assumption:
54+
// The only case in which there is more than one line of text is, when we parsed a multiline macro.
55+
//
56+
// We hence may safely ignore any subsequent lines from our existing label because these correspond
57+
// only to lines of a multiline macro, which we ought to replace anyway.
58+
final Line head = lines.get(0);
59+
Assert.assertTrue(head.content().contains("if"));
60+
final String indent = StringUtils.getLeadingWhitespace(head.content());
61+
62+
final String newText = indent + "#if " + formula.toString(NodeWriter.javaSymbols);
63+
64+
// We might have replaced multiple lines by a single line here.
65+
// In this case, some line numbers got lost and any variation tree using this updated label somewhere might not
66+
// have consecutive line numbering anymore. We could consider inserting empty lines to retain
67+
// consecutive line numbers but that might be a more artifical change than inconsecutive line numbers.
68+
return new DiffLinesLabel(
69+
List.of(new Line(newText, head.lineNumber())),
70+
l.getDiffTrailingLines()
71+
);
72+
}
73+
74+
private static void elim(VariationTreeNode<DiffLinesLabel> subtree) {
4075
// We simplify only annotations.
4176
if (!subtree.isAnnotation()) return;
4277

43-
final List<VariationTreeNode<L>> children = subtree.getChildren();
78+
final List<VariationTreeNode<DiffLinesLabel>> children = subtree.getChildren();
4479

4580
// When there are no children, 'subtree' is an empty annotation that can be eliminated.
4681
if (children.isEmpty()) {
4782
subtree.drop();
4883
}
4984
// When there is exactly one child and that child is an 'else' or 'elif' we can simplify that nesting.
5085
else if (children.size() == 1) {
51-
final VariationTreeNode<L> child = children.getFirst();
86+
final VariationTreeNode<DiffLinesLabel> child = children.getFirst();
5287

5388
if ((subtree.isIf() || subtree.isElif()) && (child.isElif() || child.isElse())) {
5489
// determine new feaure mapping
@@ -57,6 +92,7 @@ else if (children.size() == 1) {
5792
newFormula = and(newFormula, child.getFormula());
5893
}
5994
subtree.setFormula(newFormula);
95+
subtree.setLabel(updatedLabel(subtree.getLabel(), newFormula));
6096

6197
// simplify tree
6298
child.drop();
@@ -66,7 +102,7 @@ else if (children.size() == 1) {
66102
}
67103

68104
@Override
69-
public void transform(VariationTree<L> tree) {
70-
tree.forAllPostorder(this::elim);
105+
public void transform(VariationTree<DiffLinesLabel> tree) {
106+
tree.forAllPostorder(EliminateEmptyAlternatives::elim);
71107
}
72108
}

0 commit comments

Comments
 (0)