1818import org .variantsync .diffdetective .variation .diff .Time ;
1919import org .variantsync .diffdetective .variation .diff .VariationDiff ;
2020import org .variantsync .diffdetective .variation .diff .parse .VariationDiffParseOptions ;
21+ import org .variantsync .diffdetective .variation .diff .patching .Patching ;
2122import org .variantsync .diffdetective .variation .diff .source .VariationDiffSource ;
2223import org .variantsync .diffdetective .variation .diff .view .DiffView ;
2324import org .variantsync .diffdetective .variation .tree .VariationTree ;
2425import org .variantsync .diffdetective .variation .tree .view .relevance .Configure ;
2526import org .variantsync .diffdetective .variation .tree .view .relevance .Relevance ;
2627
28+ import com .github .gumtreediff .actions .Diff ;
29+
2730public 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}
0 commit comments