Skip to content

Commit 2b20e33

Browse files
committed
refactor: move joinNode into DiffNode
This makes it more discoverable and consistent with `DiffNode.split`.
1 parent 1f24ebc commit 2b20e33

3 files changed

Lines changed: 32 additions & 24 deletions

File tree

src/main/java/org/variantsync/diffdetective/util/Assert.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public static void assertFalse(boolean condition, String errorMessage) {
8686
}
8787

8888
/** Throws {@link AssertionError} with {@code errorMessage} as error message. */
89-
public static void fail(String errorMessage) {
89+
public static <T> T fail(String errorMessage) {
9090
throw new AssertionError(errorMessage);
9191
}
9292

src/main/java/org/variantsync/diffdetective/variation/diff/DiffNode.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.variantsync.functjonal.Cast;
1515

1616
import java.util.*;
17+
import java.util.function.BiFunction;
1718
import java.util.function.Function;
1819
import java.util.stream.Stream;
1920

@@ -412,6 +413,35 @@ public DiffNode<L> split(Time time) {
412413
return other;
413414
}
414415

416+
/**
417+
* Merges {@code other} into this node.
418+
* {@code other} is removed from the graph and this node inherits all of its edges. This
419+
* node and {@code other} need to be compatible (exist at different times and have the
420+
* same {@link getNodeType node type}).
421+
* <p>
422+
* Both {@code this} and {@code other} must not be {@link isRoot the root}.
423+
*
424+
* @param other the node which is removed from the graph
425+
* @param joinLabels returns a label that should represent the two passed labels
426+
*/
427+
public void join(DiffNode<L> other, BiFunction<L, L, L> joinLabels) {
428+
Time time = switch (diffType) {
429+
case ADD -> BEFORE;
430+
case REM -> AFTER;
431+
case NON -> Assert.fail("Attempt to join a node that already exists at both times.");
432+
};
433+
Assert.assertEquals(other.diffType, DiffType.thatExistsOnlyAt(time));
434+
Assert.assertEquals(getNodeType(), other.getNodeType());
435+
Assert.assertFalse(isRoot());
436+
Assert.assertFalse(other.isRoot());
437+
438+
diffType = DiffType.NON;
439+
label.setInnerLabel(joinLabels.apply(getLabel(), other.getLabel()));
440+
441+
this.stealChildrenOf(other);
442+
other.getParent(time).replaceChild(other, this, time);
443+
}
444+
415445
/**
416446
* Replaces a child of this node with another node.
417447
* <p>

src/main/java/org/variantsync/diffdetective/variation/diff/construction/GumTreeDiff.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Map;
2323

2424
import static org.variantsync.diffdetective.variation.diff.DiffType.ADD;
25-
import static org.variantsync.diffdetective.variation.diff.DiffType.NON;
2625
import static org.variantsync.diffdetective.variation.diff.DiffType.REM;
2726
import static org.variantsync.diffdetective.variation.diff.Time.AFTER;
2827
import static org.variantsync.diffdetective.variation.diff.Time.BEFORE;
@@ -218,7 +217,7 @@ public static <L extends Label> DiffNode<L> improveMatching(DiffNode<L> tree, Ma
218217
afterNode.split(BEFORE);
219218
}
220219

221-
joinNode(beforeNode, afterNode);
220+
beforeNode.join(afterNode, (beforeLabel, afterLabel) -> beforeLabel);
222221
}
223222

224223
Assert.assertTrue(beforeNode.isNon());
@@ -229,27 +228,6 @@ public static <L extends Label> DiffNode<L> improveMatching(DiffNode<L> tree, Ma
229228
return tree;
230229
}
231230

232-
/**
233-
* Merges {@code afterNode} into {@code beforeNode} such that {@code beforeNode.isNon() ==
234-
* true}. Essentially, an implicit matching is inserted between {@code beforeNode} and {@code
235-
* afterNode}.
236-
*
237-
* This method doesn't change the {@code BEFORE} and {@code AFTER} projection of {@code
238-
* beforeNode}.
239-
*
240-
* @param beforeNode the node which is will exist {@code BEFORE} and {@code AFTER} the edit
241-
* @param afterNode the node which is discarded
242-
*/
243-
private static <L extends Label> void joinNode(DiffNode<L> beforeNode, DiffNode<L> afterNode) {
244-
Assert.assertTrue(beforeNode.isRem());
245-
Assert.assertTrue(afterNode.isAdd());
246-
247-
beforeNode.diffType = NON;
248-
249-
beforeNode.stealChildrenOf(afterNode);
250-
afterNode.getParent(AFTER).replaceChild(afterNode, beforeNode, AFTER);
251-
}
252-
253231
/**
254232
* Makes the implicit matching of a {@code VariationDiff} explicit.
255233
*

0 commit comments

Comments
 (0)