From 61fa5e3ad817f30bcc2d30eed508bbc7a22b3496 Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 12 Jan 2018 23:20:04 +0100 Subject: [PATCH 1/6] Commit by Martin Monperrus on 12 January 2018 --- .../java/spoon/reflect/code/CtComment.java | 3 +++ .../compiler/jdt/JDTCommentBuilder.java | 1 + .../support/reflect/code/CtCommentImpl.java | 9 +++++++ .../reflect/declaration/CtElementImpl.java | 11 ++++++-- .../java/spoon/test/javadoc/JavaDocTest.java | 25 +++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/spoon/reflect/code/CtComment.java b/src/main/java/spoon/reflect/code/CtComment.java index aff4a8cb2dc..87ec65ea749 100644 --- a/src/main/java/spoon/reflect/code/CtComment.java +++ b/src/main/java/spoon/reflect/code/CtComment.java @@ -80,4 +80,7 @@ enum CommentType { @Override CtComment clone(); + + /** Utility method to for casting the object, throws an exception if not of the correct type */ + CtJavaDoc asJavaDoc(); } diff --git a/src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java b/src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java index 65ec6269bc1..63fa42896f7 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java @@ -167,6 +167,7 @@ private CtComment parseTags(CtComment comment, String commentContent) { String currentTagContent = ""; CtJavaDocTag.TagType currentTag = null; + // TODO: remove the " *", see spoon.test.javadoc.JavaDocTest.testJavaDocReprint() String[] lines = commentContent.split("\n"); for (int i = 0; i < lines.length; i++) { String line = lines[i].trim(); diff --git a/src/main/java/spoon/support/reflect/code/CtCommentImpl.java b/src/main/java/spoon/support/reflect/code/CtCommentImpl.java index 013f1a8cec0..88fceb9fe2b 100644 --- a/src/main/java/spoon/support/reflect/code/CtCommentImpl.java +++ b/src/main/java/spoon/support/reflect/code/CtCommentImpl.java @@ -18,6 +18,7 @@ import spoon.reflect.annotations.MetamodelPropertyField; import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtJavaDoc; import spoon.reflect.path.CtRole; import spoon.reflect.visitor.CtVisitor; @@ -105,4 +106,12 @@ public int hashCode() { public CtComment clone() { return (CtComment) super.clone(); } + + @Override + public CtJavaDoc asJavaDoc() { + if (this instanceof CtJavaDoc) { + return (CtJavaDoc) this; + } + throw new IllegalStateException("not a javadoc comment"); + } } diff --git a/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java b/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java index 32ca7318e91..92c461aeae5 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java @@ -19,6 +19,8 @@ import org.apache.log4j.Logger; import spoon.reflect.annotations.MetamodelPropertyField; import spoon.reflect.code.CtComment; +import spoon.reflect.code.CtJavaDoc; +import spoon.reflect.code.CtJavaDocTag; import spoon.reflect.cu.SourcePosition; import spoon.reflect.declaration.CtAnnotation; import spoon.reflect.declaration.CtElement; @@ -172,10 +174,15 @@ public List> getAnnotations() { public String getDocComment() { for (CtComment ctComment : comments) { if (ctComment.getCommentType() == CtComment.CommentType.JAVADOC) { - return ctComment.getContent(); + StringBuffer result = new StringBuffer(); + result.append(ctComment.getContent()+System.lineSeparator()); + for (CtJavaDocTag tag: ((CtJavaDoc)ctComment).getTags()) { + result.append(tag.toString()); // the tag already contains a new line + } + return result.toString(); } } - return null; + return ""; } public SourcePosition getPosition() { diff --git a/src/test/java/spoon/test/javadoc/JavaDocTest.java b/src/test/java/spoon/test/javadoc/JavaDocTest.java index 8bdd8543d3e..c89decc67e1 100644 --- a/src/test/java/spoon/test/javadoc/JavaDocTest.java +++ b/src/test/java/spoon/test/javadoc/JavaDocTest.java @@ -40,6 +40,31 @@ public void testJavaDocReprint() throws Exception { + " return null;" + System.lineSeparator() + " }" + System.lineSeparator() + "}", aClass.toString()); + + // contract: getDocComment never returns null, it returns an empty string if no comment + assertEquals("", aClass.getDocComment()); + + // contract: getDocComment returns the comment content together with the tag content + assertEquals("Creates an annotation type." + System.lineSeparator() + + "* @param owner" + System.lineSeparator() + + " * \t\tthe package of the annotation type" + System.lineSeparator() + + "* @param simpleName" + System.lineSeparator() + + " * \t\tthe name of annotation" + System.lineSeparator() + , aClass.getMethodsByName("create").get(0).getDocComment()); + assertEquals(2, aClass.getMethodsByName("create").get(0).getComments().get(0).asJavaDoc().getTags().size()); + + // JavaDocTest#testJavaDocReprint() + // good first bug to welcome new contributors + // uncomment the assertion and get it passing! + // there remains a minor problem with tags, they are printed with the "* " before the content + // and the spaces before the * are not consistently handled + // here is the correct assertion +// assertEquals("Creates an annotation type." + System.lineSeparator() +// + "@param owner" + System.lineSeparator() +// + " \t\tthe package of the annotation type" + System.lineSeparator() +// + " @param simpleName" + System.lineSeparator() +// + " \t\tthe name of annotation" + System.lineSeparator() +// , aClass.getMethodsByName("create").get(0).getDocComment()); } @Test From 29b5dae8cba4518006fa83fc578cf07185b7696e Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 12 Jan 2018 23:23:02 +0100 Subject: [PATCH 2/6] up --- src/test/java/spoon/test/pkg/PackageTest.java | 2 +- src/test/java/spoon/test/template/TemplateTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/spoon/test/pkg/PackageTest.java b/src/test/java/spoon/test/pkg/PackageTest.java index e8a8651e0f5..0d7e4e53bdb 100644 --- a/src/test/java/spoon/test/pkg/PackageTest.java +++ b/src/test/java/spoon/test/pkg/PackageTest.java @@ -56,7 +56,7 @@ public void testPackage() throws Exception { CtPackage ctPackage = clazz.getPackage(); Assert.assertEquals("spoon.test.pkg.name", ctPackage.getQualifiedName()); - Assert.assertNull(ctPackage.getDocComment()); + Assert.assertEquals("", ctPackage.getDocComment()); assertTrue(CtPackage.class.isAssignableFrom(ctPackage.getParent().getClass())); ctPackage = (CtPackage) ctPackage.getParent(); diff --git a/src/test/java/spoon/test/template/TemplateTest.java b/src/test/java/spoon/test/template/TemplateTest.java index ca7811efb71..e232d6df52f 100644 --- a/src/test/java/spoon/test/template/TemplateTest.java +++ b/src/test/java/spoon/test/template/TemplateTest.java @@ -263,7 +263,7 @@ private void assertCommentHasGeneratedBy(CtElement e, String templateQName, Map< String docComment = e.getDocComment(); String generatedByMember = elementToGeneratedByMember.get(e); if (generatedByMember == null) { - assertNull(docComment); + assertEquals("", docComment); // assertTrue(e.getPosition()==null || e.getPosition() instanceof NoSourcePosition); } else { assertNotNull("Javadoc comment is missing for "+e.toString(), docComment); From 03ae4b71868d2c9a344fce0c04fe72704f90a556 Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 12 Jan 2018 23:34:53 +0100 Subject: [PATCH 3/6] Commit by Martin Monperrus on 12 January 2018 --- .../java/spoon/support/reflect/declaration/CtElementImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java b/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java index 92c461aeae5..a0c67b854a8 100644 --- a/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java +++ b/src/main/java/spoon/support/reflect/declaration/CtElementImpl.java @@ -175,8 +175,8 @@ public String getDocComment() { for (CtComment ctComment : comments) { if (ctComment.getCommentType() == CtComment.CommentType.JAVADOC) { StringBuffer result = new StringBuffer(); - result.append(ctComment.getContent()+System.lineSeparator()); - for (CtJavaDocTag tag: ((CtJavaDoc)ctComment).getTags()) { + result.append(ctComment.getContent() + System.lineSeparator()); + for (CtJavaDocTag tag: ((CtJavaDoc) ctComment).getTags()) { result.append(tag.toString()); // the tag already contains a new line } return result.toString(); From 153f6c51c2c825e8a729f6afb7b64941261c972c Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 12 Jan 2018 23:39:11 +0100 Subject: [PATCH 4/6] Commit by Martin Monperrus on 12 January 2018 --- src/main/java/spoon/reflect/declaration/CtElement.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/spoon/reflect/declaration/CtElement.java b/src/main/java/spoon/reflect/declaration/CtElement.java index 0a609d6b6d1..d545b83583a 100644 --- a/src/main/java/spoon/reflect/declaration/CtElement.java +++ b/src/main/java/spoon/reflect/declaration/CtElement.java @@ -99,7 +99,13 @@ CtAnnotation getAnnotation( /** * Returns the text of the documentation ("javadoc") comment of this - * element. The documentation is also accessible via {@link #getComments()}. + * element. It contains the text of Javadoc together with the tags. + * + * If one only wants only the text without the tag, one can call `getComments().get(0).getContent()` + * + * If one wants to analyze the tags, one can call `getComments().get(0).asJavaDoc().getTags()` + * + * See also {@link #getComments()}.and {@link spoon.reflect.code.CtJavaDoc} */ @DerivedProperty String getDocComment(); From 59891005760cc085f6fd5d18a8df221643473deb Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Sat, 13 Jan 2018 00:14:33 +0100 Subject: [PATCH 5/6] Commit by Martin Monperrus on 13 January 2018 --- src/main/java/spoon/reflect/factory/CodeFactory.java | 3 +++ src/test/java/spoon/test/template/TemplateTest.java | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/spoon/reflect/factory/CodeFactory.java b/src/main/java/spoon/reflect/factory/CodeFactory.java index 48f5a836962..fa12aa8ef11 100644 --- a/src/main/java/spoon/reflect/factory/CodeFactory.java +++ b/src/main/java/spoon/reflect/factory/CodeFactory.java @@ -673,6 +673,9 @@ public CtCodeSnippetStatement createCodeSnippetStatement(String statement) { * @return a new CtComment */ public CtComment createComment(String content, CtComment.CommentType type) { + if (type == CtComment.CommentType.JAVADOC) { + return factory.Core().createJavaDoc().setContent(content); + } return factory.Core().createComment().setContent(content).setCommentType(type); } diff --git a/src/test/java/spoon/test/template/TemplateTest.java b/src/test/java/spoon/test/template/TemplateTest.java index e232d6df52f..815ce58c839 100644 --- a/src/test/java/spoon/test/template/TemplateTest.java +++ b/src/test/java/spoon/test/template/TemplateTest.java @@ -256,7 +256,7 @@ class Context { * Generated by spoon.test.template.testclasses.inheritance.SubTemplate#var(SubTemplate.java:51) * Generated by spoon.test.template.testclasses.inheritance.SubTemplate$InnerClass(SubTemplate.java:76) */ - private static final Pattern generatedByRE = Pattern.compile("Generated by ([^$#\\(]+)([^\\(]*)\\(([^\\.]+)\\.java:(\\d+)\\)"); + private static final Pattern generatedByRE = Pattern.compile(".*Generated by ([^$#\\(]+)([^\\(]*)\\(([^\\.]+)\\.java:(\\d+)\\).*", Pattern.MULTILINE | Pattern.DOTALL); private static final Pattern typeMemberRE = Pattern.compile("[^\\.$#]+$"); private void assertCommentHasGeneratedBy(CtElement e, String templateQName, Map elementToGeneratedByMember) { @@ -269,7 +269,7 @@ private void assertCommentHasGeneratedBy(CtElement e, String templateQName, Map< assertNotNull("Javadoc comment is missing for "+e.toString(), docComment); int idx = docComment.indexOf("Generated by"); assertTrue("Javadoc comment doesn't contain Generated by. There is:\n"+docComment, idx>=0); - Matcher m = generatedByRE.matcher(docComment.substring(idx)); + Matcher m = generatedByRE.matcher(docComment); assertTrue("Unexpected Generated by:\n"+docComment, m.matches()); assertEquals(templateQName, m.group(1)); assertEquals(generatedByMember, m.group(2)); From 540cd0a1938bffe95b9dc03122b87a7a9857167c Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Sat, 13 Jan 2018 00:26:55 +0100 Subject: [PATCH 6/6] Commit by Martin Monperrus on 13 January 2018 --- src/test/java/spoon/test/pkg/PackageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/spoon/test/pkg/PackageTest.java b/src/test/java/spoon/test/pkg/PackageTest.java index 0d7e4e53bdb..07e7f99e9da 100644 --- a/src/test/java/spoon/test/pkg/PackageTest.java +++ b/src/test/java/spoon/test/pkg/PackageTest.java @@ -76,7 +76,7 @@ public void testPackage() throws Exception { ctPackage = (CtPackage) ctPackage.getParent(); Assert.assertEquals("spoon.test", ctPackage.getQualifiedName()); - Assert.assertNull(ctPackage.getDocComment()); + Assert.assertEquals("", ctPackage.getDocComment()); } @Test