INRIA / INRIA/spoon

[Bug]: `CtComment.insertAfter` and `insertBefore` don't work

Open
#4,875 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
2k
Forks
392
Avg merge
11h 24m
Merged PRs (30d)
36

Description

### Describe the bug

Trying to insert any element before or after a `CtComment` doesn't work. In some cases simply nothing is changed when calling `insertAfter`/`insertBefore`. When trying to insert before or after a comment which is followed by an if statement an exception `should not happen` is thrown.

A workaround to insert before the comment is to insert before it's parent statement. But inserting directly after the comment isn't possible this way.

### Source code you are trying to analyze/transform

```Java
public class Foo {
public static int foo(int[] a) {
// 1
int x = 0;
// 2
int y = 1;
// 3
if(x > y) {
return x - y;
}
return y - x;
}
}
```

### Source code for your Spoon processing

```Java
Launcher spoon = new Launcher();
spoon.addInputResource(new VirtualFile(inputProgram));
CtModel model = spoon.buildModel();

List comments = model.getElements(new TypeFilter<>(CtComment.class));
CtMethod method = model.getElements(new TypeFilter<>(CtMethod.class)).get(0);

System.out.println("### Initial:");
System.out.println(spoon.createPrettyPrinter().printElement(method));

System.out.println();
System.out.println("### Trying insertBefore and insertAfter on comment 1:");
comments.get(0).insertBefore(method.getFactory().createComment("a", CommentType.INLINE));
comments.get(0).insertAfter(method.getFactory().createComment("b", CommentType.INLINE));
System.out.println(spoon.createPrettyPrinter().printElement(method));

System.out.println();
System.out.println("### Trying insertBefore and insertAfter on parent statement of comment 2:");
((CtStatement)comments.get(1).getParent()).insertBefore(method.getFactory().createComment("c", CommentType.INLINE));
((CtStatement)comments.get(1).getParent()).insertAfter(method.getFactory().createComment("d", CommentType.INLINE));
System.out.println(spoon.createPrettyPrinter().printElement(method));

System.out.println();
System.out.println("### Trying insertBefore and insertAfter on comment 3:");
comments.get(2).insertBefore(method.getFactory().createComment("e", CommentType.INLINE));
comments.get(2).insertAfter(method.getFactory().createComment("f", CommentType.INLINE));
System.out.println(spoon.createPrettyPrinter().printElement(method));
```

### Actual output

```Java
### Initial:
public static int foo(int[] a) {
// 1
int x = 0;
// 2
int y = 1;
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on comment 1:
public static int foo(int[] a) {
// 1
int x = 0;
// 2
int y = 1;
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on parent statement of comment 2:
public static int foo(int[] a) {
// 1
int x = 0;
// c
// 2
int y = 1;
// d
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on comment 3:
Exception in thread "main" java.lang.IllegalArgumentException: should not happen
at spoon.support.reflect.code.CtStatementImpl$InsertVisitor.visitCtIf(CtStatementImpl.java:104)
at spoon.support.reflect.code.CtIfImpl.accept(CtIfImpl.java:36)
at spoon.reflect.visitor.CtInheritanceScanner.scan(CtInheritanceScanner.java:185)
at spoon.support.reflect.code.CtStatementImpl.insertBefore(CtStatementImpl.java:72)
at spoon.support.reflect.code.CtStatementImpl.insertBefore(CtStatementImpl.java:57)
at spoon.support.reflect.code.CtStatementImpl.insertBefore(CtStatementImpl.java:245)
at InsertAfterOrBeforeComment.main(InsertAfterOrBeforeComment.java:56)
```

### Expected output

```Java
### Initial:
public static int foo(int[] a) {
// 1
int x = 0;
// 2
int y = 1;
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on comment 1:
public static int foo(int[] a) {
// a
// 1
// b
int x = 0;
// 2
int y = 1;
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on parent statement of comment 2:
public static int foo(int[] a) {
// a
// 1
// b
int x = 0;
// c
// 2
int y = 1;
// d
// 3
if (x > y) {
return x - y;
}
return y - x;
}

### Trying insertBefore and insertAfter on comment 3:
public static int foo(int[] a) {
// a
// 1
// b
int x = 0;
// c
// 2
int y = 1;
// d
// e
// 3
// f
if (x > y) {
return x - y;
}
return y - x;
}
```

### Spoon Version

10.2.0-beta-17 and 10.2.0-beta-8

### JVM Version

17

### What operating system are you using?

Windows 10 64 bit

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.