Repository: SpoonLabs/gumtree-spoon-ast-diff
Pull request #93 (2019-04-11 08:29:50)

Avoid creating Modifiers node with any Modifiable element
Avoid creating Modifiers node when the Modifiable element has not any modifiers.

Related to issue #92 https://github.com/SpoonLabs/gumtree-spoon-ast-diff/issues/92



Patch:
diff --git a/src/main/java/gumtree/spoon/builder/NodeCreator.java b/src/main/java/gumtree/spoon/builder/NodeCreator.java
index 609145d..87ac0fe 100644
--- a/src/main/java/gumtree/spoon/builder/NodeCreator.java
+++ b/src/main/java/gumtree/spoon/builder/NodeCreator.java
@@ -8,7 +8,6 @@ import com.github.gumtreediff.tree.ITree;
 
 import spoon.reflect.declaration.CtMethod;
 import spoon.reflect.declaration.CtModifiable;
-import spoon.reflect.declaration.CtParameter;
 import spoon.reflect.declaration.CtVariable;
 import spoon.reflect.declaration.ModifierKind;
 import spoon.reflect.reference.CtTypeReference;
@@ -17,7 +16,8 @@ import spoon.reflect.visitor.CtInheritanceScanner;
 /**
  * responsible to add additional nodes only overrides scan* to add new nodes
  */
-class NodeCreator extends CtInheritanceScanner {
+public class NodeCreator extends CtInheritanceScanner {
+	public static final String MODIFIERS = "Modifiers_";
 	private final TreeScanner builder;
 
 	NodeCreator(TreeScanner builder) {
@@ -26,8 +26,12 @@ class NodeCreator extends CtInheritanceScanner {
 
 	@Override
 	public void scanCtModifiable(CtModifiable m) {
+
+		if (m.getModifiers().isEmpty())
+			return;
+
 		// We add the type of modifiable element
-		String type = "Modifiers_" + getClassName(m.getClass().getSimpleName());
+		String type = MODIFIERS + getClassName(m.getClass().getSimpleName());
 		ITree modifiers = builder.createNode(type, "");
 
 		// We create a virtual node


Test patch:
diff --git a/src/test/java/gumtree/spoon/AstComparatorTest.java b/src/test/java/gumtree/spoon/AstComparatorTest.java
index 42dc236..1185507 100644
--- a/src/test/java/gumtree/spoon/AstComparatorTest.java
+++ b/src/test/java/gumtree/spoon/AstComparatorTest.java
@@ -15,11 +15,12 @@ import org.junit.Ignore;
 import org.junit.Test;
 
 import com.github.gumtreediff.matchers.Mapping;
-import com.github.gumtreediff.tree.ITree;
 
+import gumtree.spoon.builder.NodeCreator;
 import gumtree.spoon.builder.SpoonGumTreeBuilder;
 import gumtree.spoon.diff.Diff;
 import gumtree.spoon.diff.DiffImpl;
+import gumtree.spoon.diff.operations.InsertOperation;
 import gumtree.spoon.diff.operations.MoveOperation;
 import gumtree.spoon.diff.operations.Operation;
 import gumtree.spoon.diff.operations.OperationKind;
@@ -36,6 +37,7 @@ import spoon.reflect.code.CtReturn;
 import spoon.reflect.code.CtThrow;
 import spoon.reflect.declaration.CtClass;
 import spoon.reflect.declaration.CtElement;
+import spoon.reflect.declaration.CtParameter;
 import spoon.reflect.declaration.CtType;
 import spoon.reflect.factory.Factory;
 import spoon.support.compiler.VirtualFile;
@@ -1662,11 +1664,10 @@ public class AstComparatorTest {
 	@Test
 	public void testVarargs() throws Exception {
 		// https://github.com/GumTreeDiff/gumtree/issues/120
-		CtClass c1 = Launcher.parseClass(" class BehaviorCall {\n"
-				+ "   void foo(String s)}\n" + "}\n" + "\n" + "}");
+		CtClass c1 = Launcher.parseClass(" class BehaviorCall {\n" + "   void foo(String s)}\n" + "}\n" + "\n" + "}");
 
-		CtClass c2 = Launcher.parseClass(" class BehaviorCall {\n"
-				+ "   void foo(String... s)}\n" + "}\n" + "\n" + "}");
+		CtClass c2 = Launcher
+				.parseClass(" class BehaviorCall {\n" + "   void foo(String... s)}\n" + "}\n" + "\n" + "}");
 
 		AstComparator diff = new AstComparator();
 		Diff result = diff.compare(c1, c2);
@@ -1676,7 +1677,44 @@ public class AstComparatorTest {
 
 		assertEquals(1, actions.size());
 		// the type is now an array
-		assertTrue(result.containsOperations(OperationKind.Update, "VARIABLE_TYPE(CtTypeReferenceImpl)", "java.lang.String", "java.lang.String[]"));
+		assertTrue(result.containsOperations(OperationKind.Update, "VARIABLE_TYPE(CtTypeReferenceImpl)",
+				"java.lang.String", "java.lang.String[]"));
 	}
 
+	@Test
+	public void testModifEmpty() throws Exception {
+
+		CtClass c1a = Launcher.parseClass(" class BehaviorCall implements Call{\n"
+				+ "final AtomicReference failureRef = new AtomicReference<>();\n"
+				+ "final CountDownLatch latch = new CountDownLatch(1);\n" + "\n" + " enqueue(new Callback<T>() {\n"
+				+ "  @Override public void onResponse(Response<T> response) {\n" + "     responseRef.set(response);\n"
+				+ "     latch.countDown();\n" + "   }\n" + "}\n" + ")\n" + "\n" + "}");
+
+		CtClass c2a = Launcher.parseClass("class BehaviorCall implements Call {\n"
+				+ "final AtomicReference failureRef = new AtomicReference<>();\n"
+				+ "final CountDownLatch latch = new CountDownLatch(1);\n" + "enqueue(new Callback() {\n"
+				// Here the difference
+				+ "@override public void onResponse(Call call, Response response) {\n" + "responseRef.set(response);\n"
+				+ "latch.countDown();\n" + "}\n" + "}\n" + ")\n" + "}");
+
+		AstComparator diff = new AstComparator();
+		Diff resulta = diff.compare(c1a, c2a);
+
+		List<Operation> actions = resulta.getRootOperations();
+		resulta.debugInformation();
+
+		assertEquals(1, actions.size());
+
+		assertTrue(actions.get(0) instanceof InsertOperation);
+		assertTrue(actions.get(0).getSrcNode() instanceof CtParameter);
+		DiffImpl idiff = (DiffImpl) resulta;
+
+		for (Mapping map : idiff.getMappingsComp()) {
+			if ((map.getFirst().toPrettyString(idiff.getContext()).startsWith(NodeCreator.MODIFIERS))) {
+				assertFalse(map.getFirst().getChildren().isEmpty());
+				assertFalse(map.getSecond().getChildren().isEmpty());
+			}
+		}
+
+	}
 }
diff --git a/src/test/resources/examples/spoon.json b/src/test/resources/examples/spoon.json
index 3afb0a8..94b1b43 100644
--- a/src/test/resources/examples/spoon.json
+++ b/src/test/resources/examples/spoon.json
@@ -214,11 +214,6 @@
                   "label": "org.gjt.sp.jedit.View",
                   "type": "VARIABLE_TYPE",
                   "children": []
-                },
-                {
-                  "label": "",
-                  "type": "Modifiers_Parameter",
-                  "children": []
                 }
               ]
             },
@@ -230,11 +225,6 @@
                   "label": "java.lang.String",
                   "type": "VARIABLE_TYPE",
                   "children": []
-                },
-                {
-                  "label": "",
-                  "type": "Modifiers_Parameter",
-                  "children": []
                 }
               ]
             },
@@ -877,11 +867,6 @@
                   "type": "VARIABLE_TYPE",
                   "children": []
                 },
-                {
-                  "label": "",
-                  "type": "Modifiers_LocalVariable",
-                  "children": []
-                },
                 {
                   "label": "javax.swing.JScrollPane(java.awt.Component)",
                   "type": "ConstructorCall",
@@ -1098,11 +1083,6 @@
                   "label": "org.gjt.sp.jedit.EBMessage",
                   "type": "VARIABLE_TYPE",
                   "children": []
-                },
-                {
-                  "label": "",
-                  "type": "Modifiers_Parameter",
-                  "children": []
                 }
               ]
             },
@@ -1191,11 +1171,6 @@
                   "type": "VARIABLE_TYPE",
                   "children": []
                 },
-                {
-                  "label": "",
-                  "type": "Modifiers_LocalVariable",
-                  "children": []
-                },
                 {
                   "label": "org.gjt.sp.jedit.jEdit#getProperty()",
                   "type": "Invocation",
@@ -1374,11 +1349,6 @@
                   "type": "VARIABLE_TYPE",
                   "children": []
                 },
-                {
-                  "label": "",
-                  "type": "Modifiers_LocalVariable",
-                  "children": []
-                },
                 {
                   "label": "QuickNotepadOptionPane#makeFont()",
                   "type": "Invocation",
@@ -1729,11 +1699,6 @@
                       "type": "VARIABLE_TYPE",
                       "children": []
                     },
-                    {
-                      "label": "",
-                      "type": "Modifiers_LocalVariable",
-                      "children": []
-                    },
                     {
                       "label": "java.io.FileWriter(java.lang.String)",
                       "type": "ConstructorCall",
@@ -1804,11 +1769,6 @@
                           "label": "java.io.IOException",
                           "type": "VARIABLE_TYPE",
                           "children": []
-                        },
-                        {
-                          "label": "",
-                          "type": "Modifiers_CatchVariable",
-                          "children": []
                         }
                       ]
                     },
@@ -1911,11 +1871,6 @@
                   "type": "VARIABLE_TYPE",
                   "children": []
                 },
-                {
-                  "label": "",
-                  "type": "Modifiers_LocalVariable",
-                  "children": []
-                },
                 {
                   "label": "org.gjt.sp.jedit.GUIUtilities#showVFSFileDialog(org.gjt.sp.jedit.View,\u003cunknown\u003e,int,boolean)",
                   "type": "Invocation",
@@ -2320,11 +2275,6 @@
                   "type": "VARIABLE_TYPE",
                   "children": []
                 },
-                {
-                  "label": "",
-                  "type": "Modifiers_LocalVariable",
-                  "children": []
-                },
                 {
                   "label": "null",
                   "type": "Literal",
@@ -2379,11 +2329,6 @@
                       "type": "VARIABLE_TYPE",
                       "children": []
                     },
-                    {
-                      "label": "",
-                      "type": "Modifiers_LocalVariable",
-                      "children": []
-                    },
                     {
                       "label": "java.lang.StringBuffer(int)",
                       "type": "ConstructorCall",
@@ -2405,11 +2350,6 @@
                       "label": "java.lang.String",
                       "type": "VARIABLE_TYPE",
                       "children": []
-                    },
-                    {
-                      "label": "",
-                      "type": "Modifiers_LocalVariable",
-                      "children": []
                     }
                   ]
                 },
@@ -2530,11 +2470,6 @@
                           "label": "java.io.FileNotFoundException",
                           "type": "VARIABLE_TYPE",
                           "children": []
-                        },
-                        {
-                          "label": "",
-                          "type": "Modifiers_CatchVariable",
-                          "children": []
                         }
                       ]
                     },
@@ -2612,11 +2547,6 @@
                           "label": "java.io.IOException",
                           "type": "VARIABLE_TYPE",
                           "children": []
-                        },
-                        {
-                          "label": "",
-                          "type": "Modifiers_CatchVariable",
-                          "children": []
                         }
                       ]
                     },