Skip to content

Commit 65f796e

Browse files
committed
Create a VariationLabel for representing nested variation trees
1 parent b3f65e5 commit 65f796e

19 files changed

Lines changed: 98 additions & 52 deletions

src/main/java/org/variantsync/diffdetective/editclass/EditClassCatalogue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public interface EditClassCatalogue {
3535
default EditClass match(DiffNode<?> node)
3636
{
3737
if (!node.isArtifact()) {
38-
throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!");
38+
throw new IllegalArgumentException("Expected an artifact node but got " + node.getNodeType() + "!");
3939
}
4040

4141
final List<EditClass> classessToCheck = byType().get(node.diffType);

src/main/java/org/variantsync/diffdetective/editclass/proposed/ProposedEditClasses.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public EditClass match(DiffNode<?> node)
7575
// Each returned value is not null but an actual edit class object.
7676
// Since the given node may be any node, we have proven that every node is classified by at least one edit class.
7777
if (!node.isArtifact()) {
78-
throw new IllegalArgumentException("Expected an artifact node but got " + node.nodeType + "!");
78+
throw new IllegalArgumentException("Expected an artifact node but got " + node.getNodeType() + "!");
7979
}
8080

8181
if (node.isAdd()) {

src/main/java/org/variantsync/diffdetective/mining/RWCompositePatternNodeFormat.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public String toLabel(final DiffNode<? extends DiffLinesLabel> node) {
1111
if (node.isArtifact()) {
1212
return ProposedEditClasses.Instance.match(node).getName() + "<br>" + node.getLabel();
1313
} else {
14-
return node.diffType + "_" + switch (node.nodeType) {
14+
return node.diffType + "_" + switch (node.getNodeType()) {
1515
case IF -> "mapping<br> " + node.getLabel();
1616
case ELSE -> "else";
1717
case ELIF -> "elif<br>" + node.getLabel();
18-
default -> node.nodeType + "<br>" + node.getLabel();
18+
default -> node.getNodeType() + "<br>" + node.getLabel();
1919
};
2020
}
2121
}

src/main/java/org/variantsync/diffdetective/mining/formats/DebugMiningDiffNodeFormat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public String toLabel(final DiffNode<? extends DiffLinesLabel> node) {
2020
if (node.isArtifact()) {
2121
return ProposedEditClasses.Instance.match(node).getName();
2222
} else {
23-
return node.diffType + "_" + node.nodeType;
23+
return node.diffType + "_" + node.getNodeType();
2424
}
2525
}
2626

src/main/java/org/variantsync/diffdetective/mining/formats/ReleaseMiningDiffNodeFormat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public String toLabel(DiffNode<? extends DiffLinesLabel> node) {
4242
if (node.isArtifact()) {
4343
return ARTIFACT_PREFIX + toId(ProposedEditClasses.Instance.match(node));
4444
} else {
45-
return ANNOTATION_PREFIX + node.diffType.ordinal() + node.nodeType.ordinal();
45+
return ANNOTATION_PREFIX + node.diffType.ordinal() + node.getNodeType().ordinal();
4646
}
4747
}
4848

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.variantsync.diffdetective.variation;
2+
3+
import java.util.List;
4+
5+
import org.variantsync.diffdetective.variation.tree.HasNodeType;
6+
import org.variantsync.diffdetective.variation.tree.VariationTree; // For Javadoc
7+
import org.variantsync.functjonal.Cast;
8+
9+
/**
10+
* Extends an inner {@link Label}, the object language, with variability, the meta language.
11+
*
12+
* This class allows encoding of multiple levels of variability in the sense of variation trees of
13+
* variation trees. Such higher-order variation trees can be encoded in a single tree structure
14+
* because the result of configuring a variation tree is still a tree. In other words: the object
15+
* language of a {@code VariationTree<L>} is a tree with labels {@code L}. The trick is that a
16+
* variation tree is just a tree with labels {@code VariationLabel<L>}.
17+
*
18+
* @param <L> the label of the trees (the object language) over which variability is introduced
19+
* @see VariationTree
20+
*/
21+
public class VariationLabel<L extends Label> implements Label, HasNodeType {
22+
private NodeType type;
23+
private L innerLabel;
24+
25+
public VariationLabel(NodeType type, L innerLabel) {
26+
this.type = type;
27+
this.innerLabel = innerLabel;
28+
}
29+
30+
public L getInnerLabel() {
31+
return innerLabel;
32+
}
33+
34+
public void setInnerLabel(L innerLabel) {
35+
this.innerLabel = innerLabel;
36+
}
37+
38+
@Override
39+
public List<String> getLines() {
40+
return innerLabel.getLines();
41+
}
42+
43+
@Override
44+
public NodeType getNodeType() {
45+
return type;
46+
}
47+
48+
@Override
49+
public VariationLabel<L> clone() {
50+
return new VariationLabel<L>(type, Cast.unchecked(innerLabel.clone()));
51+
}
52+
}

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

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.variantsync.diffdetective.variation.DiffLinesLabel;
99
import org.variantsync.diffdetective.variation.Label;
1010
import org.variantsync.diffdetective.variation.NodeType;
11+
import org.variantsync.diffdetective.variation.VariationLabel;
1112
import org.variantsync.diffdetective.variation.tree.HasNodeType;
1213
import org.variantsync.diffdetective.variation.tree.VariationNode;
1314
import org.variantsync.functjonal.Cast;
@@ -40,16 +41,15 @@ public class DiffNode<L extends Label> implements HasNodeType {
4041
public DiffType diffType;
4142

4243
/**
43-
* The node type of this node, which determines the type of the represented
44-
* element in the diff (e.g., mapping or artifact).
44+
* The label together with the node type of this node, which determines the type of the
45+
* represented element in the diff (e.g., mapping or artifact).
4546
*/
46-
public final NodeType nodeType;
47+
public final VariationLabel<L> label;
4748

4849
private DiffLineNumber from = DiffLineNumber.Invalid();
4950
private DiffLineNumber to = DiffLineNumber.Invalid();
5051

5152
private Node featureMapping;
52-
private L label;
5353

5454
/**
5555
* The parents {@link DiffNode} before and after the edit.
@@ -94,11 +94,10 @@ public DiffNode(DiffType diffType, NodeType nodeType,
9494
children[AFTER.ordinal()] = new ArrayList<>();
9595

9696
this.diffType = diffType;
97-
this.nodeType = nodeType;
97+
this.label = new VariationLabel<>(nodeType, label);
9898
this.from = fromLines;
9999
this.to = toLines;
100100
this.featureMapping = featureMapping;
101-
this.label = label;
102101
}
103102

104103
/**
@@ -136,15 +135,15 @@ public static <L extends Label> DiffNode<L> createArtifact(DiffType diffType, Di
136135
* Returns the lines in the diff that are represented by this DiffNode as a single text.
137136
*/
138137
public L getLabel() {
139-
return label;
138+
return label.getInnerLabel();
140139
}
141140

142141
/**
143142
* Sets the lines in the diff that are represented by this DiffNode to the given code.
144143
* Lines are identified by linebreak characters.
145144
*/
146-
public void setLabel(L label) {
147-
this.label = label;
145+
public void setLabel(L newLabel) {
146+
label.setInnerLabel(newLabel);
148147
}
149148

150149
/**
@@ -535,7 +534,7 @@ public DiffType getDiffType() {
535534

536535
@Override
537536
public NodeType getNodeType() {
538-
return nodeType;
537+
return label.getNodeType();
539538
}
540539

541540
/**
@@ -568,13 +567,13 @@ public int getID() {
568567
id |= diffType.ordinal();
569568

570569
id <<= NodeType.getRequiredBitCount();
571-
id |= nodeType.ordinal();
570+
id |= getNodeType().ordinal();
572571
return id;
573572
}
574573

575574
/**
576575
* Reconstructs a node from the given id and sets the given label.
577-
* An id uniquely determines a node's {@link DiffNode#nodeType}, {@link DiffNode#diffType}, and {@link DiffLineNumber#inDiff line number in the diff}.
576+
* An id uniquely determines a node's {@link DiffNode#getNodeType}, {@link DiffNode#diffType}, and {@link DiffLineNumber#inDiff line number in the diff}.
578577
* The almost-inverse function is {@link DiffNode#getID()} but the conversion is not lossless.
579578
* @param id The id from which to reconstruct the node.
580579
* @param label The label the node should have.
@@ -657,7 +656,7 @@ public void assertConsistency() {
657656
if (this.isIf() || this.isElif()) {
658657
Assert.assertTrue(this.getFormula() != null, "If or elif without feature mapping!");
659658
} else {
660-
Assert.assertTrue(this.getFormula() == null, "Node with type " + nodeType + " has a non null feature mapping");
659+
Assert.assertTrue(this.getFormula() == null, "Node with type " + getNodeType() + " has a non null feature mapping");
661660
}
662661
}
663662

@@ -692,7 +691,7 @@ public static <T extends VariationNode<T, L>, L extends Label> DiffNode<L> uncha
692691
new DiffLineNumber(from, from, from),
693692
new DiffLineNumber(to, to, to),
694693
variationNode.getFormula(),
695-
Cast.unchecked(variationNode.getLabel().clone())
694+
variationNode.getLabel()
696695
);
697696
}
698697

@@ -802,11 +801,11 @@ private static <L extends Label> boolean isSameAs(DiffNode<L> a, DiffNode<L> b,
802801
public String toString() {
803802
String s;
804803
if (isArtifact()) {
805-
s = String.format("%s_%s from %d to %d", diffType, nodeType, from.inDiff(), to.inDiff());
804+
s = String.format("%s_%s from %d to %d", diffType, getNodeType(), from.inDiff(), to.inDiff());
806805
} else if (isRoot()) {
807806
s = "ROOT";
808807
} else {
809-
s = String.format("%s_%s from %d to %d with \"%s\"", diffType, nodeType,
808+
s = String.format("%s_%s from %d to %d with \"%s\"", diffType, getNodeType(),
810809
from.inDiff(), to.inDiff(), featureMapping);
811810
}
812811
return s;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public Projection<L> upCast() {
5454

5555
@Override
5656
public NodeType getNodeType() {
57-
return getBackingNode().nodeType;
57+
return getBackingNode().getNodeType();
5858
}
5959

6060
@Override

src/main/java/org/variantsync/diffdetective/variation/diff/serialize/LineGraphImport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private static DiffTree<DiffLinesLabel> parseDiffTree(final String lineGraph, fi
144144
if (root != null) {
145145
throw new RuntimeException("Not a DiffTree: Got more than one root! Got \"" + root + "\" and \"" + v + "\"!");
146146
}
147-
if (v.nodeType == NodeType.IF) {
147+
if (v.getNodeType() == NodeType.IF) {
148148
root = v;
149149
} else {
150150
throw new RuntimeException("Not a DiffTree but a DiffGraph: The node \"" + v + "\" is not labeled as IF but has no parents!");
@@ -156,7 +156,7 @@ private static DiffTree<DiffLinesLabel> parseDiffTree(final String lineGraph, fi
156156
throw new RuntimeException("Not a DiffTree but a DiffGraph: No root found!");
157157
}
158158

159-
// countRootTypes.merge(root.nodeType, 1, Integer::sum);
159+
// countRootTypes.merge(root.getNodeType(), 1, Integer::sum);
160160

161161
return new DiffTree<>(root, diffTreeSource);
162162
} else {

src/main/java/org/variantsync/diffdetective/variation/diff/serialize/nodeformat/DebugDiffNodeFormat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
public class DebugDiffNodeFormat<L extends Label> implements DiffNodeLabelFormat<L> {
1212
@Override
1313
public String toLabel(final DiffNode<? extends L> node) {
14-
return node.diffType + "_" + node.nodeType + "_\"" +
14+
return node.diffType + "_" + node.getNodeType() + "_\"" +
1515
DiffNodeLabelPrettyfier.prettyPrintIfAnnotationOr(
1616
node,
1717
FileUtils.replaceLineEndings(node.getLabel().toString().trim().replaceAll("\t", " "), "<br>"))

0 commit comments

Comments
 (0)