Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,12 @@ public <A extends Annotation> void visitCtAnnotation(CtAnnotation<A> e) {
// now we make sure that there is a parent
// if there is no parent
if (!comment.isParentInitialized()) {
// that's a serious error, there is something to debug
LOGGER.error("\"" + comment + "\" cannot be added into the AST, with parent " + commentParent.getClass()
+ " at " + commentParent.getPosition().toString()
// A specialized visitor may not find a suitable child, for example when a
// comment is placed next to an operator or inside an empty module directive.
LOGGER.error("\"" + comment + "\" cannot be added to a specialized AST child; attaching it to parent "
+ commentParent.getClass() + " at " + commentParent.getPosition().toString()
+ ", please report the bug by posting on https://github.com/INRIA/spoon/issues/2482");
commentParent.addComment(comment);
}
}

Expand Down
67 changes: 53 additions & 14 deletions src/test/java/spoon/test/comment/CommentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import spoon.support.DefaultCoreFactory;
import spoon.support.JavaOutputProcessor;
import spoon.support.StandardEnvironment;
import spoon.support.compiler.VirtualFile;
import spoon.support.compiler.jdt.JDTSnippetCompiler;
import spoon.support.reflect.code.CtCommentImpl;
import spoon.test.comment.testclasses.BlockComment;
Expand Down Expand Up @@ -106,6 +107,7 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand Down Expand Up @@ -1277,34 +1279,71 @@ public void testAnnotationComments(CtModel model) {
}

@ModelTest("./src/test/java/spoon/test/comment/testclasses/ArrayAccessComments.java")
@GitHubIssue(issueNumber = 2482, fixed = false)
@GitHubIssue(issueNumber = 2482, fixed = true)
public void testArrayAccessComments(CtModel model) {
//contract: comments at array accesses should be properly added to the AST
List<CtComment> comments = model.getElements(new TypeFilter<>(CtComment.class));
List<CtArrayAccess<?, ?>> arrayAccesses = model.getElements(new TypeFilter<>(CtArrayAccess.class));

assertEquals(2,comments.size());
assertEquals("comment 1", comments.get(0).getContent());
assertEquals("comment 2", comments.get(1).getContent());

assertEquals(1, arrayAccesses.get(0).getComments().size());
assertEquals("comment 1", arrayAccesses.get(0).getComments().get(0).getContent());
assertEquals(1, arrayAccesses.get(1).getComments().size());
assertEquals("comment 2", arrayAccesses.get(1).getComments().get(0).getContent());
assertThat(comments)
.extracting(CtComment::getContent)
.containsExactly("comment 1", "comment 2");
assertThat(arrayAccesses)
.satisfiesExactly(
first -> assertThat(first.getComments())
.extracting(CtComment::getContent)
.containsExactly("comment 1"),
second -> assertThat(second.getComments())
.extracting(CtComment::getContent)
.containsExactly("comment 2"));
}

@ModelTest("./src/test/java/spoon/test/comment/testclasses/BinaryOperatorComments.java")
@GitHubIssue(issueNumber = 2482, fixed = false)
@GitHubIssue(issueNumber = 2482, fixed = true)
public void testBinaryOperatorComments(CtModel model) {
//contract: comments at binary operators should be properly added to the AST
List<CtComment> comments = model.getElements(new TypeFilter<>(CtComment.class));
List<CtBinaryOperator<?>> binaryOperators = model.getElements(new TypeFilter<>(CtBinaryOperator.class));

assertEquals(1, comments.size());
assertEquals("comment 1", comments.get(0).getContent());
assertThat(comments)
.extracting(CtComment::getContent)
.containsExactly("comment 1");
assertThat(binaryOperators)
.singleElement()
.satisfies(binaryOperator -> assertThat(binaryOperator.getComments())
.extracting(CtComment::getContent)
.containsExactly("comment 1"));
}

assertEquals(1, binaryOperators.get(0).getComments().size());
assertEquals("comment 1", binaryOperators.get(0).getComments().get(0).getContent());
@ModelTest(code = "@Deprecated(/* marker */) class CommentInEmptyAnnotation {}")
public void testCommentInEmptyAnnotationFallsBackToAnnotation(CtModel model) {
// contract: a comment is retained on its enclosing annotation when the annotation has no value expression
assertThat(model.getElements(new TypeFilter<CtAnnotation<?>>(CtAnnotation.class)))
.singleElement()
.satisfies(annotation -> assertThat(annotation.getComments())
.extracting(CtComment::getContent)
.containsExactly("marker"));
}

@Test
public void testCommentInModuleWithoutDirectivesFallsBackToModule() {
// contract: a comment is retained on its enclosing module when there is no directive to receive it
Launcher launcher = new Launcher();
launcher.getEnvironment().setComplianceLevel(9);
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource(new VirtualFile("""
module comment.fallback {
// exports disabled
}
""", "module-info.java"));

CtModel model = launcher.buildModel();
assertThat(model.getAllModules())
.filteredOn(candidate -> candidate.getSimpleName().equals("comment.fallback"))
.singleElement()
.satisfies(module -> assertThat(module.getComments())
.extracting(CtComment::getContent)
.containsExactly("exports disabled"));
}

@ModelTest("./src/test/java/spoon/test/comment/testclasses/TypeParameterComments.java")
Expand Down
Loading