Repository: SpoonLabs/gumtree-spoon-ast-diff (java)

Issue:
Incorrect role in parent is returned for `CtWrapper` elements
Fetching role of `CtWrapper` elements in their parents returns the element's grandparent's role instead. For example, calling `getRoleInParent` on `final` in `private final int x` returns `CtRole.TYPE_MEMBER` instead of `CtRole.MODIFIER`. This is because parent of `final` is `private final int x` and its role is `CtRole.TYPE_MEMBER`.

The reason for this issue is that the role of `CtWrapper` elements is not set in `NodeCreator.java` as can been for the two lines below.
https://github.com/SpoonLabs/gumtree-spoon-ast-diff/blob/da117118feace452f60b6383c2d66cddb0b2fe12/src/main/java/gumtree/spoon/builder/NodeCreator.java#L55

https://github.com/SpoonLabs/gumtree-spoon-ast-diff/blob/da117118feace452f60b6383c2d66cddb0b2fe12/src/main/java/gumtree/spoon/builder/NodeCreator.java#L105

A solution could be to use the [other constructor](https://github.com/SpoonLabs/gumtree-spoon-ast-diff/blob/3e392ca49e09a43eb48e618d54bf98a2b97fb99e/src/main/java/gumtree/spoon/builder/CtWrapper.java#L33) which would set the role as well.

More information: https://github.com/SpoonLabs/gumtree-spoon-ast-diff/pull/158.

Pull request:
Fix role of `CtWrapper` elements in their parent
Fixes #160 

These changes explicitly assign `roleInParent` to the following elements.
- [x] Complete collection of modifier (`CtVirtualElement`)
- [x] Individual modifiers (`CtWrapper`)
- ~[ ] Super type~

I am not sure how I can test for the role of a `CtTypeReference` (`SUPER_TYPE` in this case). Need some help there.

Patch:
diff --git a/src/main/java/gumtree/spoon/builder/NodeCreator.java b/src/main/java/gumtree/spoon/builder/NodeCreator.java
index c3bf219..19c3cc6 100644
--- a/src/main/java/gumtree/spoon/builder/NodeCreator.java
+++ b/src/main/java/gumtree/spoon/builder/NodeCreator.java
@@ -36,7 +36,7 @@ public class NodeCreator extends CtInheritanceScanner {
 		ITree modifiers = builder.createNode(type, "");
 
 		// We create a virtual node
-		modifiers.setMetadata(SpoonGumTreeBuilder.SPOON_OBJECT, new CtVirtualElement(type, m, m.getModifiers()));
+		modifiers.setMetadata(SpoonGumTreeBuilder.SPOON_OBJECT, new CtVirtualElement(type, m, m.getModifiers(), CtRole.MODIFIER));
 
 		// ensuring an order (instead of hashset)
 		// otherwise some flaky tests in CI
@@ -52,7 +52,7 @@ public class NodeCreator extends CtInheritanceScanner {
 			ITree modifier = builder.createNode("Modifier", kind.toString());
 			modifiers.addChild(modifier);
 			// We wrap the modifier (which is not a ctelement)
-			modifier.setMetadata(SpoonGumTreeBuilder.SPOON_OBJECT, new CtWrapper(kind, m));
+			modifier.setMetadata(SpoonGumTreeBuilder.SPOON_OBJECT, new CtWrapper(kind, m, CtRole.MODIFIER));
 		}
 		builder.addSiblingNode(modifiers);
 


Test patch:
diff --git a/src/test/java/gumtree/spoon/diff/support/SpoonSupportTest.java b/src/test/java/gumtree/spoon/diff/support/SpoonSupportTest.java
index 436ec72..85e2867 100644
--- a/src/test/java/gumtree/spoon/diff/support/SpoonSupportTest.java
+++ b/src/test/java/gumtree/spoon/diff/support/SpoonSupportTest.java
@@ -5,6 +5,8 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
+import gumtree.spoon.builder.CtVirtualElement;
+import gumtree.spoon.builder.CtWrapper;
 import org.junit.Test;
 
 import com.github.gumtreediff.tree.ITree;
@@ -16,7 +18,12 @@ import gumtree.spoon.diff.operations.DeleteOperation;
 import gumtree.spoon.diff.operations.InsertOperation;
 import gumtree.spoon.diff.operations.Operation;
 import gumtree.spoon.diff.operations.UpdateOperation;
+import spoon.reflect.declaration.CtElement;
 import spoon.reflect.declaration.CtMethod;
+import spoon.reflect.declaration.ModifierKind;
+import spoon.reflect.path.CtRole;
+
+import java.io.File;
 
 public class SpoonSupportTest {
 
@@ -162,4 +169,27 @@ public class SpoonSupportTest {
 
 	}
 
+	@Test
+	public void testRoleOfFinalInParent() throws Exception {
+		File fl = new File("src/test/resources/examples/roleInParent/final/left.java");
+		File fr = new File("src/test/resources/examples/roleInParent/final/right.java");
+
+		Diff diff = new AstComparator().compare(fl, fr);
+
+		CtWrapper<?> finalNode = (CtWrapper<?>) diff.getRootOperations().get(0).getSrcNode();
+
+		assertEquals(CtRole.MODIFIER, finalNode.getRoleInParent());
+	}
+
+	@Test
+	public void testRoleOfModifiersInParent() throws Exception {
+		File fl = new File("src/test/resources/examples/roleInParent/modifiers/left.java");
+		File fr = new File("src/test/resources/examples/roleInParent/modifiers/right.java");
+
+		Diff diff = new AstComparator().compare(fl, fr);
+
+		CtVirtualElement modifiers = (CtVirtualElement) diff.getRootOperations().get(0).getSrcNode();
+
+		assertEquals(CtRole.MODIFIER, modifiers.getRoleInParent());
+	}
 }
diff --git a/src/test/resources/examples/roleInParent/final/left.java b/src/test/resources/examples/roleInParent/final/left.java
new file mode 100644
index 0000000..8bc285b
--- /dev/null
+++ b/src/test/resources/examples/roleInParent/final/left.java
@@ -0,0 +1,3 @@
+class Final {
+    private static int x;
+}
diff --git a/src/test/resources/examples/roleInParent/final/right.java b/src/test/resources/examples/roleInParent/final/right.java
new file mode 100644
index 0000000..65f33da
--- /dev/null
+++ b/src/test/resources/examples/roleInParent/final/right.java
@@ -0,0 +1,3 @@
+class Final {
+    private static final int x;
+}
diff --git a/src/test/resources/examples/roleInParent/modifiers/left.java b/src/test/resources/examples/roleInParent/modifiers/left.java
new file mode 100644
index 0000000..3c5aff2
--- /dev/null
+++ b/src/test/resources/examples/roleInParent/modifiers/left.java
@@ -0,0 +1,3 @@
+class Modifiers {
+    int x;
+}
diff --git a/src/test/resources/examples/roleInParent/modifiers/right.java b/src/test/resources/examples/roleInParent/modifiers/right.java
new file mode 100644
index 0000000..33ae2af
--- /dev/null
+++ b/src/test/resources/examples/roleInParent/modifiers/right.java
@@ -0,0 +1,3 @@
+class Modifiers {
+    private static final int x;
+}