Skip to content

Commit

Permalink
fix: fix Problems with javadoc parameters @exception and others (#3035)
Browse files Browse the repository at this point in the history
@exception, @Serialdata, @serialFiel
  • Loading branch information
Egor18 authored and monperrus committed Jun 26, 2019
1 parent 8e19856 commit 3af0801
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 72 deletions.
55 changes: 9 additions & 46 deletions src/main/java/spoon/javadoc/internal/JavadocBlockTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
package spoon.javadoc.internal;

import spoon.reflect.code.CtJavaDocTag;

import java.io.Serializable;

/**
Expand All @@ -24,68 +26,29 @@
*/
public class JavadocBlockTag implements Serializable {

/**
* The type of tag: it could either correspond to a known tag (param, return, etc.) or represent
* an unknown tag.
*/
public enum Type {
AUTHOR,
DEPRECATED,
EXCEPTION,
PARAM,
RETURN,
SEE,
SERIAL,
SERIAL_DATA,
SERIAL_FIELD,
SINCE,
THROWS,
VERSION,
UNKNOWN;

Type() {
this.keyword = name();
}

private String keyword;

boolean hasName() {
return this == PARAM || this == THROWS;
}

static Type fromName(String tagName) {
for (Type t : Type.values()) {
if (t.keyword.toUpperCase().equals(tagName.toUpperCase())) {
return t;
}
}
return UNKNOWN;
}
}

private Type type;
private CtJavaDocTag.TagType type;
private JavadocDescription content;
private String name = "";
private String tagName;

public JavadocBlockTag(Type type, String content) {
public JavadocBlockTag(CtJavaDocTag.TagType type, String content) {
this.type = type;
this.tagName = type.keyword;
this.tagName = type.getName();
this.content = Javadoc.parseText(content);
}

public JavadocBlockTag(String tagName, String content) {
this(Type.fromName(tagName), content);
this(CtJavaDocTag.TagType.tagFromName(tagName), content);
this.tagName = tagName;
}

public JavadocBlockTag(String tagName, String paramName, String content) {
this(Type.fromName(tagName), content);
this(CtJavaDocTag.TagType.tagFromName(tagName), content);
this.tagName = tagName;
this.name = paramName;
}

public Type getType() {
public CtJavaDocTag.TagType getType() {
return type;
}

Expand Down Expand Up @@ -154,4 +117,4 @@ public String toString() {
+ name
+ '}';
}
}
}
53 changes: 33 additions & 20 deletions src/main/java/spoon/reflect/code/CtJavaDocTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import spoon.reflect.annotations.PropertyGetter;
import spoon.reflect.annotations.PropertySetter;

import java.util.Arrays;

import static spoon.reflect.path.CtRole.COMMENT_CONTENT;
import static spoon.reflect.path.CtRole.JAVADOC_TAG_VALUE;
import static spoon.reflect.path.CtRole.DOCUMENTATION_TYPE;
Expand All @@ -32,26 +34,40 @@ public interface CtJavaDocTag extends CtElement {
* Define the possible type for a tag
*/
enum TagType {
AUTHOR,
DEPRECATED,
EXCEPTION,
PARAM,
RETURN,
SEE,
SERIAL,
SERIAL_DATA,
SERIAL_FIELD,
SINCE,
THROWS,
VERSION,
UNKNOWN;
AUTHOR("author"),
DEPRECATED("deprecated"),
EXCEPTION("exception"),
PARAM("param"),
RETURN("return"),
SEE("see"),
SERIAL("serial"),
SERIAL_DATA("serialData"),
SERIAL_FIELD("serialField"),
SINCE("since"),
THROWS("throws"),
VERSION("version"),
UNKNOWN("unknown");

TagType(String name) {
this.name = name;
}

private String name;

/**
* Get tag name
* @return name
*/
public String getName() {
return name;
}

/**
* Return true if the tag can have a parameter
* @return true if the tag can have a parameter
*/
public boolean hasParam() {
return this == PARAM || this == THROWS;
return this == PARAM || this == THROWS || this == EXCEPTION;
}

/**
Expand All @@ -60,12 +76,9 @@ public boolean hasParam() {
* @return the tag type
*/
public static TagType tagFromName(String tagName) {
for (TagType t : TagType.values()) {
if (t.name().toLowerCase().equals(tagName.toLowerCase())) {
return t;
}
}
return UNKNOWN;
return Arrays.stream(TagType.values())
.filter(v -> v.name.equals(tagName))
.findFirst().orElse(UNKNOWN);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@


import java.lang.annotation.Annotation;

import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.CtAbstractInvocation;
import spoon.reflect.code.CtArrayAccess;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class CtJavaDocTagImpl extends CtElementImpl implements CtJavaDocTag {

@MetamodelPropertyField(role = DOCUMENTATION_TYPE)
private CtJavaDocTag.TagType type;
private TagType type;
@MetamodelPropertyField(role = COMMENT_CONTENT)
private String content;
@MetamodelPropertyField(role = JAVADOC_TAG_VALUE)
Expand All @@ -30,7 +30,7 @@ public TagType getType() {

@Override
public <E extends CtJavaDocTag> E setType(String type) {
this.setType(CtJavaDocTag.TagType.tagFromName(type));
this.setType(TagType.tagFromName(type));
return (E) this;
}

Expand Down
53 changes: 51 additions & 2 deletions src/test/java/spoon/test/javadoc/JavaDocTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,24 @@
import spoon.Launcher;
import spoon.OutputType;
import spoon.SpoonAPI;
import spoon.javadoc.internal.JavadocDescriptionElement;
import spoon.javadoc.internal.JavadocInlineTag;
import spoon.reflect.CtModel;
import spoon.reflect.code.CtComment;
import spoon.reflect.code.CtJavaDoc;
import spoon.reflect.code.CtJavaDocTag;
import spoon.reflect.code.CtJavaDocTag.TagType;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtEnum;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.CtScanner;
import spoon.support.reflect.code.CtJavaDocImpl;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.javadoc.testclasses.Bar;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static spoon.testing.utils.Check.assertCtElementEquals;
Expand Down Expand Up @@ -132,4 +138,47 @@ public void testBugSetContent() {
assertEquals("foo", j.getTags().get(0).getContent());
}

@Test
public void testTagsParameters() {
// contract: @throws and @exception should have proper params
Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/javadoc/testclasses/A.java");
launcher.getEnvironment().setCommentEnabled(true);
launcher.getEnvironment().setNoClasspath(true);
CtModel model = launcher.buildModel();

List<CtJavaDoc> javadocs = model.getElements(new TypeFilter<>(CtJavaDoc.class));

CtJavaDocTag throwsTag = javadocs.get(0).getTags().get(0);
CtJavaDocTag exceptionTag = javadocs.get(1).getTags().get(0);

assertEquals("IllegalArgumentException", throwsTag.getParam());
assertEquals("FileNotFoundException", exceptionTag.getParam());
}

@Test
public void testJavadocTagNames() {
//contract: we should handle all possible javadoc tags properly
Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/javadoc/testclasses/B.java");
launcher.getEnvironment().setCommentEnabled(true);
launcher.getEnvironment().setNoClasspath(true);
CtModel model = launcher.buildModel();

CtType<?> type = model.getAllTypes().stream().findFirst().get();
assertEquals(TagType.VERSION, type.getElements(new TypeFilter<>(CtEnum.class)).get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.AUTHOR, type.getMethodsByName("m1").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.DEPRECATED, type.getMethodsByName("m2").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.EXCEPTION, type.getMethodsByName("m3").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.PARAM, type.getMethodsByName("m4").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.RETURN, type.getMethodsByName("m5").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.SEE, type.getMethodsByName("m6").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.SERIAL, type.getField("m7").getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.SERIAL_DATA, type.getMethodsByName("m8").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.SERIAL_FIELD, type.getField("m9").getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.SINCE, type.getMethodsByName("m10").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.THROWS, type.getMethodsByName("m11").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
assertEquals(TagType.UNKNOWN, type.getMethodsByName("m12").get(0).getElements(new TypeFilter<>(CtJavaDoc.class)).get(0).getTags().get(0).getType());
}

}
20 changes: 20 additions & 0 deletions src/test/java/spoon/test/javadoc/testclasses/A.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package spoon.test.javadoc.testclasses;

import java.io.FileNotFoundException;

public class A {

/**
* @throws IllegalArgumentException if ....
*/
void m1() {

}

/**
* @exception FileNotFoundException if ....
*/
void m2() {

}
}
69 changes: 69 additions & 0 deletions src/test/java/spoon/test/javadoc/testclasses/B.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package spoon.test.javadoc.testclasses;

public class B {

/**
* @version 42
*/
enum Something { ONE, TWO, THREE }

/**
* @author somebody
*/
void m1() {}

/**
* @deprecated
*/
void m2() {}

/**
* @exception RuntimeException if ...
*/
void m3() {}

/**
* @param a ...
*/
void m4(int a) {}

/**
* @return 42
*/
int m5() { return 42; }

/**
* @see B
*/
void m6() {}

/**
* @serial description
*/
int m7;

/**
* @serialData description
*/
void m8() {}

/**
* @serialField description
*/
int m9;

/**
* @since 42
*/
void m10() {}

/**
* @throws RuntimeException if ...
*/
void m11() {}

/**
* @somethingInconsistent ...
*/
void m12() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
import spoon.reflect.code.CtJavaDocTag;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtCodeSnippet;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.ModifierKind;
import spoon.support.modelobs.ActionBasedChangeListenerImpl;
import spoon.support.modelobs.action.Action;
Expand Down

0 comments on commit 3af0801

Please sign in to comment.