Skip to content

Commit 91f3ffa

Browse files
committed
find insert position for ADD and check neigbors for REM
1 parent c35bebc commit 91f3ffa

2 files changed

Lines changed: 157 additions & 13 deletions

File tree

src/main/java/org/variantsync/diffdetective/experiments/thesis_pm/PatchingExperiment.java

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
import org.variantsync.diffdetective.variation.diff.Time;
1919
import org.variantsync.diffdetective.variation.diff.VariationDiff;
2020
import org.variantsync.diffdetective.variation.diff.parse.VariationDiffParseOptions;
21+
import org.variantsync.diffdetective.variation.diff.patching.Patching;
2122
import org.variantsync.diffdetective.variation.diff.source.VariationDiffSource;
2223
import org.variantsync.diffdetective.variation.diff.view.DiffView;
2324
import org.variantsync.diffdetective.variation.tree.VariationTree;
2425
import org.variantsync.diffdetective.variation.tree.view.relevance.Configure;
2526
import org.variantsync.diffdetective.variation.tree.view.relevance.Relevance;
2627

28+
import com.github.gumtreediff.actions.Diff;
29+
2730
public class PatchingExperiment {
2831

2932
private static Relevance calculateFeatureSetToDeselect(VariationTree<DiffLinesLabel> variant1version1, VariationTree<DiffLinesLabel> variant1version2, VariationTree<DiffLinesLabel> variant2, boolean debug) {
@@ -74,6 +77,102 @@ private static Set<DiffNode<DiffLinesLabel>> findRootsOfSubtrees(Set<DiffNode<Di
7477
return subtreeRoots;
7578
}
7679

80+
private static boolean checkNeighbors(Time time, DiffNode<DiffLinesLabel> root,
81+
DiffNode<DiffLinesLabel> targetNodeInPatch, DiffNode<DiffLinesLabel> node) {
82+
83+
DiffNode<DiffLinesLabel> neighborBeforeTarget = null;
84+
DiffNode<DiffLinesLabel> neighborAfterTarget = null;
85+
DiffNode<DiffLinesLabel> neighborBeforeSource = null;
86+
DiffNode<DiffLinesLabel> neighborAfterSource = null;
87+
boolean correctBefore = false;
88+
boolean correctAfter = false;
89+
List<DiffNode<DiffLinesLabel>> orderedChildrenTarget = targetNodeInPatch.getChildOrder(time);
90+
if (orderedChildrenTarget.contains(node)) {
91+
int indexTarget = orderedChildrenTarget.indexOf(node);
92+
if ((indexTarget - 1) >= 0) {
93+
neighborBeforeTarget = orderedChildrenTarget.get(indexTarget - 1);
94+
}
95+
if ((indexTarget + 1) < orderedChildrenTarget.size()) {
96+
neighborAfterTarget = orderedChildrenTarget.get(indexTarget + 1);
97+
}
98+
List<DiffNode<DiffLinesLabel>> orderedChildrenSource = root.getParent(time).getChildOrder(time);
99+
int indexSource = orderedChildrenSource.indexOf(root);
100+
if ((indexSource - 1) >= 0) {
101+
neighborBeforeSource = orderedChildrenSource.get(indexSource - 1);
102+
}
103+
if ((indexSource + 1) < orderedChildrenTarget.size()) {
104+
neighborAfterSource = orderedChildrenSource.get(indexSource + 1);
105+
}
106+
if ((neighborBeforeSource != null && neighborBeforeTarget == null) || (neighborBeforeSource == null && neighborBeforeTarget != null)) {
107+
System.out.println("Different neighbors");
108+
} else if (neighborBeforeSource != null && neighborBeforeTarget != null) {
109+
if (Patching.isSameAs(neighborBeforeSource, neighborBeforeTarget, time)) {
110+
System.out.println("Same neighbor before");
111+
correctBefore = true;
112+
}
113+
} else {
114+
System.out.println("No neighbor before");
115+
correctBefore = true;
116+
}
117+
if ((neighborAfterSource != null && neighborAfterTarget == null) || (neighborAfterSource == null && neighborAfterTarget != null)) {
118+
System.out.println("Different neighbors");
119+
} else if (neighborAfterSource != null && neighborAfterTarget != null) {
120+
if (Patching.isSameAs(neighborAfterSource, neighborAfterTarget, time)) {
121+
System.out.println("Same neighbor after");
122+
correctAfter = true;
123+
}
124+
} else {
125+
System.out.println("No neighbor after");
126+
correctAfter = true;
127+
}
128+
}
129+
return correctBefore && correctAfter;
130+
}
131+
132+
private static List<Integer> findInsertPositions(Time time, DiffNode<DiffLinesLabel> root,
133+
DiffNode<DiffLinesLabel> targetNodeInPatch) {
134+
List<Integer> insertPositions = new ArrayList<Integer>();
135+
DiffNode<DiffLinesLabel> neighborBeforeSource = null;
136+
DiffNode<DiffLinesLabel> neighborAfterSource = null;
137+
List<DiffNode<DiffLinesLabel>> orderedChildrenTarget = targetNodeInPatch.getChildOrder(time);
138+
List<DiffNode<DiffLinesLabel>> orderedChildrenSource = root.getParent(time).getChildOrder(time);
139+
int indexSource = orderedChildrenSource.indexOf(root);
140+
if ((indexSource - 1) >= 0) {
141+
neighborBeforeSource = orderedChildrenSource.get(indexSource - 1);
142+
}
143+
if ((indexSource + 1) < orderedChildrenTarget.size()) {
144+
neighborAfterSource = orderedChildrenSource.get(indexSource + 1);
145+
}
146+
147+
for (int i = 0; i < orderedChildrenTarget.size(); i++) {
148+
if (neighborBeforeSource != null && neighborAfterSource != null) {
149+
if ((i + 1) < orderedChildrenTarget.size()) {
150+
boolean correctBefore = Patching.isSameAs(orderedChildrenTarget.get(i), neighborBeforeSource, time);
151+
boolean correctAfter = Patching.isSameAs(orderedChildrenTarget.get(i + 1), neighborAfterSource, time);
152+
if (correctBefore && correctAfter) {
153+
System.out.println("Found insert position");
154+
insertPositions.add(i + 1);
155+
} else if (correctBefore || correctAfter){
156+
157+
}
158+
}
159+
} else if (neighborBeforeSource != null) {
160+
if (Patching.isSameAs(orderedChildrenTarget.get(i), neighborBeforeSource, time)) {
161+
System.out.println("Found insert position");
162+
insertPositions.add(i + 1);
163+
}
164+
} else if (neighborAfterSource != null) {
165+
if ((i + 1) < orderedChildrenTarget.size()) {
166+
if (Patching.isSameAs(orderedChildrenTarget.get(i + 1), neighborAfterSource, time)) {
167+
System.out.println("Found insert position");
168+
insertPositions.add(i + 1);
169+
}
170+
}
171+
}
172+
}
173+
return insertPositions;
174+
}
175+
77176
private static void applyChanges(DiffType type, VariationDiff<DiffLinesLabel> targetVariantDiffUnchanged, VariationDiff<DiffLinesLabel> targetVariantDiffPatched, Set<DiffNode<DiffLinesLabel>> subtreeRoots, VariationDiffSource source, boolean debug) {
78177
Time time = (type == DiffType.ADD) ? Time.AFTER : Time.BEFORE;
79178

@@ -99,29 +198,38 @@ private static void applyChanges(DiffType type, VariationDiff<DiffLinesLabel> ta
99198
DiffNode<DiffLinesLabel> targetNodeInPatch = targetVariantDiffPatched.getNodeWithID(targetNodes.get(0).getID());
100199
System.out.println(targetNodeInPatch.toString());
101200
if (type == DiffType.ADD) {
102-
System.out.println("subtree added");
103-
// TODO: check for neighbors and calculate insert position
104-
targetNodeInPatch.addChild(root.deepCopy(), time);
105-
System.out.println(targetNodeInPatch.getChildOrder(time));
201+
202+
List<Integer> insertPositions = findInsertPositions(time, root, targetNodeInPatch);
203+
if (insertPositions.size() != 1) {
204+
System.out.println("no matching insert position found");
205+
} else {
206+
System.out.println("subtree added");
207+
targetNodeInPatch.insertChild(root.deepCopy(), insertPositions.get(0), time);
208+
System.out.println(targetNodeInPatch.getChildOrder(time));
209+
}
210+
106211
} else if (type == DiffType.REM) {
107212
List<DiffNode<DiffLinesLabel>> nodesToRem = new ArrayList<DiffNode<DiffLinesLabel>>();
108213
System.out.println("Root: " + root.toString());
109214
System.out.println("Children: " + targetNodeInPatch.getAllChildrenSet());
110-
targetNodeInPatch.getAllChildrenStream().forEach(node -> { if (node.isSameAs(root, time)) nodesToRem.add(node);});
111-
if (nodesToRem.size() != 1) {
215+
targetNodeInPatch.getAllChildrenStream().forEach(node -> { if (Patching.isSameAs(node, root, time)) nodesToRem.add(node);});
216+
System.out.println("Nodes to remove: " + nodesToRem);
217+
218+
List<DiffNode<DiffLinesLabel>> nodesToRemAfterCheckingNeighbors = nodesToRem.stream().filter((node) -> checkNeighbors(time, root, targetNodeInPatch, node)).toList();
219+
220+
if (nodesToRemAfterCheckingNeighbors.size() != 1) {
112221
System.out.println("too much or too less target nodes found");
113222
} else {
114223
System.out.println("subtree removed");
115-
nodesToRem.get(0).diffType = DiffType.REM;
116-
// TODO: check for neighbors
117-
nodesToRem.get(0).drop(Time.AFTER);
224+
nodesToRemAfterCheckingNeighbors.get(0).diffType = DiffType.REM;
225+
nodesToRemAfterCheckingNeighbors.get(0).getAllChildrenStream().forEach(node -> node.diffType = DiffType.REM);
226+
nodesToRemAfterCheckingNeighbors.get(0).drop(Time.AFTER);
118227
System.out.println(targetNodes.get(0).getChildOrder(Time.AFTER));
119228
}
120229
}
121230
}
122231
}
123-
}
124-
232+
}
125233

126234
private static void patchVariationTrees(VariationTree<DiffLinesLabel> sourceVariantVersion1, VariationTree<DiffLinesLabel> sourceVariantVersion2, VariationTree<DiffLinesLabel> targetVariant) {
127235
if (sourceVariantVersion1 == null || sourceVariantVersion2 == null || targetVariant == null) {
@@ -175,8 +283,8 @@ private static VariationTree<DiffLinesLabel> parseVariationTreeFromFile(String f
175283
}
176284

177285
public static void main(String[] args) {
178-
// patchVariationTrees(parseVariationTreeFromFile("exampleA1Add.cpp"), parseVariationTreeFromFile("exampleA2Add.cpp"), parseVariationTreeFromFile("exampleBAdd.cpp"));
179-
patchVariationTrees(parseVariationTreeFromFile("exampleA1Rem.cpp"), parseVariationTreeFromFile("exampleA2Rem.cpp"), parseVariationTreeFromFile("exampleBRem.cpp"));
286+
patchVariationTrees(parseVariationTreeFromFile("exampleA1Add.cpp"), parseVariationTreeFromFile("exampleA2Add.cpp"), parseVariationTreeFromFile("exampleBAdd.cpp"));
287+
// patchVariationTrees(parseVariationTreeFromFile("exampleA1Rem.cpp"), parseVariationTreeFromFile("exampleA2Rem.cpp"), parseVariationTreeFromFile("exampleBRem.cpp"));
180288
}
181289

182290
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
package org.variantsync.diffdetective.variation.diff.patching;
22

3+
import java.util.HashSet;
4+
import java.util.Iterator;
5+
import java.util.Set;
6+
7+
import org.variantsync.diffdetective.variation.Label;
8+
import org.variantsync.diffdetective.variation.diff.DiffNode;
9+
import org.variantsync.diffdetective.variation.diff.Time;
10+
311
public class Patching {
12+
public static <L extends Label> boolean isSameAs(DiffNode<L> a, DiffNode<L> b, Time time) {
13+
return isSameAs(a, b, new HashSet<>(), time);
14+
}
15+
16+
private static <L extends Label> boolean isSameAs(DiffNode<L> a, DiffNode<L> b, Set<DiffNode<L>> visited, Time time) {
17+
if (!visited.add(a)) {
18+
return true;
19+
}
20+
21+
if (!(
22+
a.getNodeType().equals(b.getNodeType()) &&
23+
// a.getFromLine().atTime(time) == (b.getFromLine().atTime(time)) &&
24+
// a.getToLine().atTime(time) == (b.getToLine().atTime(time)) &&
25+
(a.getFormula() == null ? b.getFormula() == null : a.getFormula().equals(b.getFormula())) &&
26+
a.getLabel().getLines().equals(b.getLabel().getLines())
27+
)) {
28+
return false;
29+
}
30+
31+
Iterator<DiffNode<L>> aIt = a.getAllChildren().iterator();
32+
Iterator<DiffNode<L>> bIt = b.getAllChildren().iterator();
33+
while (aIt.hasNext() && bIt.hasNext()) {
34+
if (!isSameAs(aIt.next(), bIt.next(), visited, time)) {
35+
return false;
36+
}
37+
}
438

39+
return aIt.hasNext() == bIt.hasNext();
40+
}
541
}

0 commit comments

Comments
 (0)