Skip to content

Commit f274017

Browse files
Support for @Deprecated, other JSDoc improvements (#603)
1 parent c1f4e70 commit f274017

File tree

13 files changed

+236
-33
lines changed

13 files changed

+236
-33
lines changed
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11

22
package cz.habarta.typescript.generator.compiler;
33

4+
import java.lang.reflect.Field;
45
import java.util.List;
56

67

78
public class EnumMemberModel {
8-
9+
910
private final String propertyName;
1011
private final Object/*String|Number*/ enumValue;
12+
private final Field originalField;
1113
private final List<String> comments;
1214

13-
public EnumMemberModel(String propertyName, String enumValue, List<String> comments) {
14-
this(propertyName, (Object)enumValue, comments);
15+
public EnumMemberModel(String propertyName, String enumValue, Field originalField, List<String> comments) {
16+
this(propertyName, (Object)enumValue, originalField, comments);
1517
}
1618

17-
public EnumMemberModel(String propertyName, Number enumValue, List<String> comments) {
18-
this(propertyName, (Object)enumValue, comments);
19+
public EnumMemberModel(String propertyName, Number enumValue, Field originalField, List<String> comments) {
20+
this(propertyName, (Object)enumValue, originalField, comments);
1921
}
2022

21-
private EnumMemberModel(String propertyName, Object enumValue, List<String> comments) {
23+
private EnumMemberModel(String propertyName, Object enumValue, Field originalField, List<String> comments) {
2224
this.propertyName = propertyName;
2325
this.enumValue = enumValue;
26+
this.originalField = originalField;
2427
this.comments = comments;
2528
}
2629

@@ -32,16 +35,20 @@ public Object getEnumValue() {
3235
return enumValue;
3336
}
3437

38+
public Field getOriginalField() {
39+
return originalField;
40+
}
41+
3542
public List<String> getComments() {
3643
return comments;
3744
}
3845

3946
public EnumMemberModel withPropertyName(String propertyName) {
40-
return new EnumMemberModel(propertyName, enumValue, comments);
47+
return new EnumMemberModel(propertyName, enumValue, originalField, comments);
4148
}
4249

4350
public EnumMemberModel withComments(List<String> comments) {
44-
return new EnumMemberModel(propertyName, enumValue, comments);
51+
return new EnumMemberModel(propertyName, enumValue, originalField, comments);
4552
}
4653

4754
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/compiler/ModelCompiler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ private TsModel transformEnumsToNumberBasedEnum(TsModel tsModel) {
944944
for (TsEnumModel enumModel : stringEnums) {
945945
final List<EnumMemberModel> members = new ArrayList<>();
946946
for (EnumMemberModel member : enumModel.getMembers()) {
947-
members.add(new EnumMemberModel(member.getPropertyName(), (Number) null, member.getComments()));
947+
members.add(new EnumMemberModel(member.getPropertyName(), (Number) null, member.getOriginalField(), member.getComments()));
948948
}
949949
enums.add(enumModel.withMembers(members));
950950
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/ext/ClassEnumExtension.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public TsModel transformModel(SymbolTable symbolTable, TsModel model) {
5454
List<EnumMemberModel> members = new ArrayList<>();
5555
for (Field declaredField : tsBeanModel.getOrigin().getDeclaredFields()) {
5656
if (declaredField.getType().getName().equals(tsBeanModel.getOrigin().getName())) {
57-
members.add(new EnumMemberModel(declaredField.getName(), declaredField.getName(), null));
57+
members.add(new EnumMemberModel(declaredField.getName(), declaredField.getName(), declaredField, null));
5858
}
5959
}
6060
TsEnumModel temp = new TsEnumModel(
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
package cz.habarta.typescript.generator.parser;
3+
4+
import cz.habarta.typescript.generator.compiler.EnumMemberModel;
5+
import cz.habarta.typescript.generator.util.Utils;
6+
import java.lang.reflect.AnnotatedElement;
7+
import java.lang.reflect.Field;
8+
import java.lang.reflect.Method;
9+
import java.util.Collections;
10+
import java.util.List;
11+
import java.util.function.Function;
12+
import java.util.stream.Collectors;
13+
14+
15+
public class DeprecationEnricher {
16+
17+
public Model enrichModel(Model model) {
18+
final List<BeanModel> beans = mapList(model.getBeans(), this::enrichBean);
19+
final List<EnumModel> enums = mapList(model.getEnums(), this::enrichEnum);
20+
final List<RestApplicationModel> restApplications = mapList(model.getRestApplications(), this::enrichRestApplication);
21+
return new Model(beans, enums, restApplications);
22+
}
23+
24+
private BeanModel enrichBean(BeanModel bean) {
25+
final List<PropertyModel> properties = mapList(bean.getProperties(), property -> enrichProperty(property));
26+
return bean
27+
.withProperties(properties)
28+
.withComments(addDeprecation(bean.getComments(), bean.getOrigin()));
29+
}
30+
31+
private PropertyModel enrichProperty(PropertyModel property) {
32+
if (property.getOriginalMember() instanceof Method) {
33+
final Method method = (Method) property.getOriginalMember();
34+
return enrichMethodProperty(property, method);
35+
} else if (property.getOriginalMember() instanceof Field) {
36+
final Field field = (Field) property.getOriginalMember();
37+
return enrichFieldProperty(property, field);
38+
} else {
39+
return property;
40+
}
41+
}
42+
43+
private PropertyModel enrichFieldProperty(PropertyModel property, Field field) {
44+
return property
45+
.withComments(addDeprecation(property.getComments(), field));
46+
}
47+
48+
private PropertyModel enrichMethodProperty(PropertyModel property, Method method) {
49+
return property
50+
.withComments(addDeprecation(property.getComments(), method));
51+
}
52+
53+
private EnumModel enrichEnum(EnumModel enumModel) {
54+
final List<EnumMemberModel> members = mapList(enumModel.getMembers(), enumMember -> enrichEnumMember(enumMember));
55+
return enumModel
56+
.withMembers(members)
57+
.withComments(addDeprecation(enumModel.getComments(), enumModel.getOrigin()));
58+
}
59+
60+
private EnumMemberModel enrichEnumMember(EnumMemberModel enumMember) {
61+
return enumMember
62+
.withComments(addDeprecation(enumMember.getComments(), enumMember.getOriginalField()));
63+
}
64+
65+
private RestApplicationModel enrichRestApplication(RestApplicationModel restApplicationModel) {
66+
final List<RestMethodModel> enrichedRestMethods = mapList(restApplicationModel.getMethods(), restMethod -> enrichRestMethod(restMethod));
67+
return restApplicationModel.withMethods(enrichedRestMethods);
68+
}
69+
70+
private RestMethodModel enrichRestMethod(RestMethodModel method) {
71+
return method
72+
.withComments(addDeprecation(method.getComments(), method.getOriginalMethod()));
73+
}
74+
75+
private static <R, T> List<R> mapList(List<T> list, Function<T, R> mapper) {
76+
return list.stream().map(mapper).collect(Collectors.toList());
77+
}
78+
79+
private static List<String> addDeprecation(List<String> comments, AnnotatedElement annotatedElement) {
80+
return annotatedElement != null && annotatedElement.isAnnotationPresent(Deprecated.class) && !containsDeprecatedTag(comments)
81+
? Utils.concat(comments, Collections.singletonList("@deprecated"))
82+
: comments;
83+
}
84+
85+
private static boolean containsDeprecatedTag(List<String> comments) {
86+
return comments != null
87+
? comments.stream().anyMatch(comment -> comment.startsWith("@deprecated"))
88+
: false;
89+
}
90+
91+
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson2Parser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,9 @@ private DeclarationModel parseEnumOrObjectEnum(SourceType<Class<?>> sourceClass,
720720

721721
final List<String> constantComments = getComments(constant.getAnnotation(JsonPropertyDescription.class));
722722
if (value instanceof String) {
723-
enumMembers.add(new EnumMemberModel(constant.getName(), (String) value, constantComments));
723+
enumMembers.add(new EnumMemberModel(constant.getName(), (String) value, constant, constantComments));
724724
} else if (value instanceof Number) {
725-
enumMembers.add(new EnumMemberModel(constant.getName(), (Number) value, constantComments));
725+
enumMembers.add(new EnumMemberModel(constant.getName(), (Number) value, constant, constantComments));
726726
} else {
727727
TypeScriptGenerator.getLogger().warning(String.format("'%s' enum as a @JsonValue that isn't a String or Number, ignoring", enumClass.getName()));
728728
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Javadoc.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,22 @@ private BeanModel enrichBean(BeanModel bean, String beanComment, List<TagInfo> t
8686
final PropertyModel enrichedProperty = enrichProperty(property, dFields, dMethods);
8787
enrichedProperties.add(enrichedProperty);
8888
}
89-
return bean.withProperties(enrichedProperties).withComments(Utils.concat(getComments(beanComment, tags), bean.getComments()));
89+
return bean
90+
.withProperties(enrichedProperties)
91+
.withComments(combineComments(getComments(beanComment, tags), bean.getComments()));
9092
}
9193

9294
private PropertyModel enrichProperty(PropertyModel property, List<Field> dFields, List<Method> dMethods) {
9395
String propertyComment = null;
9496
List<TagInfo> tags = null;
9597
if (property.getOriginalMember() instanceof java.lang.reflect.Method) {
96-
final Method dMethod = findJavadocMethod(property.getOriginalMember().getName(), dMethods);
98+
final java.lang.reflect.Method method = (java.lang.reflect.Method) property.getOriginalMember();
99+
final Method dMethod = findJavadocMethod(method.getName(), dMethods);
97100
propertyComment = dMethod != null ? dMethod.getComment() : null;
98101
tags = dMethod != null ? dMethod.getTag() : null;
99102
} else if (property.getOriginalMember() instanceof java.lang.reflect.Field) {
100-
final Field dField = findJavadocField(property.getOriginalMember().getName(), dFields);
103+
final java.lang.reflect.Field field = (java.lang.reflect.Field) property.getOriginalMember();
104+
final Field dField = findJavadocField(field.getName(), dFields);
101105
propertyComment = dField != null ? dField.getComment() : null;
102106
tags = dField != null ? dField.getTag() : null;
103107
}
@@ -107,7 +111,8 @@ private PropertyModel enrichProperty(PropertyModel property, List<Field> dFields
107111
propertyComment = dField != null ? dField.getComment() : null;
108112
tags = dField != null ? dField.getTag() : null;
109113
}
110-
return property.withComments(getComments(propertyComment, tags));
114+
return property
115+
.withComments(combineComments(getComments(propertyComment, tags), property.getComments()));
111116
}
112117

113118
private EnumModel enrichEnum(EnumModel enumModel) {
@@ -119,14 +124,17 @@ private EnumModel enrichEnum(EnumModel enumModel) {
119124
}
120125
final String enumComment = dEnum != null ? dEnum.getComment() : null;
121126
final List<TagInfo> tags = dEnum != null ? dEnum.getTag() : null;
122-
return enumModel.withMembers(enrichedMembers).withComments(Utils.concat(getComments(enumComment, tags), enumModel.getComments()));
127+
return enumModel
128+
.withMembers(enrichedMembers)
129+
.withComments(combineComments(getComments(enumComment, tags), enumModel.getComments()));
123130
}
124131

125132
private EnumMemberModel enrichEnumMember(EnumMemberModel enumMember, Enum dEnum) {
126133
final EnumConstant dConstant = findJavadocEnumConstant(enumMember.getPropertyName(), dEnum);
127134
final List<TagInfo> tags = dConstant != null ? dConstant.getTag(): null;
128135
final String memberComment = dConstant != null ? dConstant.getComment() : null;
129-
return enumMember.withComments(Utils.concat(getComments(memberComment, tags), enumMember.getComments()));
136+
return enumMember
137+
.withComments(combineComments(getComments(memberComment, tags), enumMember.getComments()));
130138
}
131139

132140
private RestApplicationModel enrichRestApplication(RestApplicationModel restApplicationModel) {
@@ -140,9 +148,10 @@ private RestApplicationModel enrichRestApplication(RestApplicationModel restAppl
140148

141149
private RestMethodModel enrichRestMethod(RestMethodModel method) {
142150
final Method dMethod = findJavadocMethod(method.getOriginClass(), method.getName(), dRoots);
143-
return dMethod != null
144-
? method.withComments(getComments(dMethod.getComment(), dMethod.getTag()))
145-
: method;
151+
final String comment = dMethod != null ? dMethod.getComment() : null;
152+
final List<TagInfo> tags = dMethod != null ? dMethod.getTag() : null;
153+
return method
154+
.withComments(combineComments(getComments(comment, tags), method.getComments()));
146155
}
147156

148157
// finders
@@ -257,4 +266,9 @@ private List<String> getComments(String dComments, List<TagInfo> tags) {
257266
return result;
258267
}
259268

269+
private static List<String> combineComments(List<String> firstComments, List<String> secondComments) {
270+
// consider putting tags (from both comments) after regular comments
271+
return Utils.concat(firstComments, secondComments);
272+
}
273+
260274
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/JaxrsApplicationParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ private void parseResourceMethod(Result result, ResourceContext context, Class<?
230230
// comments
231231
final List<String> comments = Swagger.getOperationComments(swaggerOperation);
232232
// create method
233-
model.getMethods().add(new RestMethodModel(resourceClass, method.getName(), resolvedModelReturnType,
233+
model.getMethods().add(new RestMethodModel(resourceClass, method.getName(), resolvedModelReturnType, method,
234234
context.rootResource, httpMethod.value(), context.path, pathParams, queryParams, entityParameter, comments));
235235
}
236236
// JAX-RS specification - 3.4.1 Sub Resources

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/MethodModel.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
package cz.habarta.typescript.generator.parser;
33

4+
import java.lang.reflect.Method;
45
import java.lang.reflect.Type;
56
import java.util.Collections;
67
import java.util.List;
@@ -12,13 +13,15 @@ public class MethodModel {
1213
protected final String name;
1314
protected final List<MethodParameterModel> parameters;
1415
protected final Type returnType;
16+
protected final Method originalMethod;
1517
protected final List<String> comments;
1618

17-
public MethodModel(Class<?> originClass, String name, List<MethodParameterModel> parameters, Type returnType, List<String> comments) {
19+
public MethodModel(Class<?> originClass, String name, List<MethodParameterModel> parameters, Type returnType, Method originalMethod, List<String> comments) {
1820
this.originClass = originClass;
1921
this.name = name;
2022
this.parameters = parameters != null ? parameters : Collections.<MethodParameterModel>emptyList();
2123
this.returnType = returnType;
24+
this.originalMethod = originalMethod;
2225
this.comments = comments;
2326
}
2427

@@ -38,12 +41,16 @@ public Type getReturnType() {
3841
return returnType;
3942
}
4043

44+
public Method getOriginalMethod() {
45+
return originalMethod;
46+
}
47+
4148
public List<String> getComments() {
4249
return comments;
4350
}
4451

4552
public MethodModel withComments(List<String> comments) {
46-
return new MethodModel(originClass, name, parameters, returnType, comments);
53+
return new MethodModel(originClass, name, parameters, returnType, originalMethod, comments);
4754
}
4855

4956
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/ModelParser.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@
2323
import java.util.Collection;
2424
import java.util.LinkedList;
2525
import java.util.List;
26+
import java.util.Map;
2627
import java.util.Queue;
2728
import java.util.function.Function;
2829
import java.util.stream.Collectors;
30+
import java.util.stream.Stream;
2931

3032

3133
public abstract class ModelParser {
3234

3335
protected final Settings settings;
3436
private final Javadoc javadoc;
37+
private final DeprecationEnricher deprecationEnricher;
3538
private final Queue<SourceType<? extends Type>> typeQueue;
3639
private final TypeProcessor commonTypeProcessor;
3740
private final List<RestApplicationParser> restApplicationParsers;
@@ -49,6 +52,7 @@ public TypeProcessor getSpecificTypeProcessor() {
4952
public ModelParser(Settings settings, TypeProcessor commonTypeProcessor, List<RestApplicationParser> restApplicationParsers) {
5053
this.settings = settings;
5154
this.javadoc = new Javadoc(settings);
55+
this.deprecationEnricher = new DeprecationEnricher();
5256
this.typeQueue = new LinkedList<>();
5357
this.restApplicationParsers = restApplicationParsers;
5458
this.commonTypeProcessor = commonTypeProcessor;
@@ -65,6 +69,7 @@ public Model parseModel(List<SourceType<Type>> types) {
6569
model = Swagger.enrichModel(model);
6670
}
6771
model = javadoc.enrichModel(model);
72+
model = deprecationEnricher.enrichModel(model);
6873
return model;
6974
}
7075

@@ -191,8 +196,9 @@ protected static DeclarationModel parseEnum(SourceType<Class<?>> sourceClass) {
191196
if (sourceClass.type.isEnum()) {
192197
@SuppressWarnings("unchecked")
193198
final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) sourceClass.type;
199+
final Map<String, Field> fields = Stream.of(enumClass.getDeclaredFields()).collect(Utils.toMap(field -> field.getName(), field -> field));
194200
for (Enum<?> enumConstant : enumClass.getEnumConstants()) {
195-
values.add(new EnumMemberModel(enumConstant.name(), enumConstant.name(), null));
201+
values.add(new EnumMemberModel(enumConstant.name(), enumConstant.name(), fields.get(enumConstant.name()), null));
196202
}
197203
}
198204
return new EnumModel(sourceClass.type, EnumKind.StringBased, values, null);

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/RestMethodModel.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
package cz.habarta.typescript.generator.parser;
33

4+
import java.lang.reflect.Method;
45
import java.lang.reflect.Type;
56
import java.util.List;
67

@@ -14,10 +15,10 @@ public class RestMethodModel extends MethodModel {
1415
private final List<RestQueryParam> queryParams;
1516
private final MethodParameterModel entityParam;
1617

17-
public RestMethodModel(Class<?> originClass, String name, Type returnType,
18+
public RestMethodModel(Class<?> originClass, String name, Type returnType, Method originalMethod,
1819
Class<?> rootResource, String httpMethod, String path, List<MethodParameterModel> pathParams, List<RestQueryParam> queryParams, MethodParameterModel entityParam,
1920
List<String> comments) {
20-
super(originClass, name, null, returnType, comments);
21+
super(originClass, name, null, returnType, originalMethod, comments);
2122
this.rootResource = rootResource;
2223
this.httpMethod = httpMethod;
2324
this.path = path;
@@ -52,7 +53,7 @@ public MethodParameterModel getEntityParam() {
5253

5354
@Override
5455
public RestMethodModel withComments(List<String> comments) {
55-
return new RestMethodModel(originClass, name, returnType, rootResource, httpMethod, path, pathParams, queryParams, entityParam, comments);
56+
return new RestMethodModel(originClass, name, returnType, originalMethod, rootResource, httpMethod, path, pathParams, queryParams, entityParam, comments);
5657
}
5758

5859
}

0 commit comments

Comments
 (0)