Skip to content

Commit 31ada51

Browse files
committed
preserve method names in records as property names, even if they have is/get prefix
1 parent aa7031e commit 31ada51

File tree

5 files changed

+30
-39
lines changed

5 files changed

+30
-39
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Generates TypeScript definitions (d.ts) for Java/Kotlin model classes using refl
44
that can be used for client-side type checking of API calls and responses.
55

66
All public getters are read by default, in a similar way to Jackson.
7-
Works with Java/Lombok/Kotlin data classes. Java records are not yet supported.
7+
Works with Java/Lombok/Kotlin data classes.
88

99
## Usage
1010

src/main/java/jvm2dts/Converter.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private String convertClass(Class<?> clazz) {
9090
.collect(toMap(RecordComponent::getName, RecordComponent::getAccessor)) :
9191
stream(clazz.getMethods())
9292
.filter(m -> !isStatic(m.getModifiers()) && m.getParameterCount() == 0 && isLikeGetter(m.getName()))
93-
.collect(toMap(Method::getName, m -> m, (m1, m2) -> m1.getReturnType().isAssignableFrom(m2.getReturnType()) ? m2 : m1));
93+
.collect(toMap(m -> toPropertyName(m.getName()), m -> m, (m1, m2) -> m1.getReturnType().isAssignableFrom(m2.getReturnType()) ? m2 : m1));
9494

9595
var methodNamesInOrder = new ArrayList<>(methodAnnotations.keySet());
9696
methodNamesInOrder.retainAll(getters.keySet());
@@ -101,7 +101,7 @@ private String convertClass(Class<?> clazz) {
101101
methodNamesInOrder.addAll(superClassGetters);
102102

103103
for (String name : methodNamesInOrder) {
104-
processProperty(getters.get(name), output, methodAnnotations);
104+
processProperty(name, getters.get(name), output, methodAnnotations);
105105
}
106106
} catch (Exception e) {
107107
logger.log(SEVERE, "Failed to convert " + clazz, e);
@@ -117,12 +117,9 @@ static boolean isLikeGetter(String methodName) {
117117
return (methodName.startsWith("get") || methodName.startsWith("is")) && !methodName.equals("getClass");
118118
}
119119

120-
private void processProperty(Method method, StringBuilder out, Map<String, List<String>> classAnnotations) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
120+
private void processProperty(String propertyName, Method method, StringBuilder out, Map<String, List<String>> classAnnotations) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
121121
var fieldBuffer = new StringBuilder();
122122

123-
var name = method.getName();
124-
var propertyName = toPropertyName(name);
125-
126123
if (propertyName == null) return;
127124
var dashPos = propertyName.indexOf('-');
128125
if (dashPos > 0) propertyName = propertyName.substring(0, dashPos);
@@ -143,7 +140,7 @@ else if (annotationName.equals("JsonProperty"))
143140
fieldBuffer.append(propertyName);
144141

145142
if (!classAnnotations.isEmpty())
146-
for (String annotation : classAnnotations.getOrDefault(name, emptyList()))
143+
for (var annotation : classAnnotations.getOrDefault(method.getName(), emptyList()))
147144
if (annotation.contains("Nullable;"))
148145
fieldBuffer.append("?");
149146

@@ -162,7 +159,7 @@ else if (annotationName.equals("JsonProperty"))
162159
typeBuffer.append(typeMapper.getTSType(isIterable ? type.getComponentType() : type));
163160
}
164161
} catch (Exception e) {
165-
logger.log(SEVERE, "Failed to convert property type for `" + name + "` in `" + method.getDeclaringClass() + "`, defaulting to `any`", e);
162+
logger.log(SEVERE, "Failed to convert property type for `" + propertyName + "` in `" + method.getDeclaringClass() + "`, defaulting to `any`", e);
166163
typeBuffer = new StringBuilder("any");
167164
}
168165
out.append(fieldBuffer);

src/main/java/jvm2dts/NameConverter.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/test/java/jvm2dts/ClassConverterTest.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ class ClassConverterTest {
1717
@Test
1818
void modelClass() {
1919
assertThat(converter.convert(Model.class)).isEqualTo("interface Model {" +
20-
"name: string; " +
2120
"age: number; " +
22-
"role: ModelRole; " +
23-
"listOfLong: number[]; " +
24-
"listOfList: string[][]; " +
2521
"details: ModelDetails; " +
26-
"id: string;}");
22+
"id: string; " +
23+
"listOfList: string[][]; " +
24+
"listOfLong: number[]; " +
25+
"name: string; " +
26+
"role: ModelRole;" +
27+
"}");
2728

2829
assertThat(converter.convert(Model.Details.class)).isEqualTo("interface ModelDetails {" +
2930
"stuff: string;}");
@@ -34,30 +35,31 @@ void primitiveTypes() {
3435
assertThat(converter.convert(Primitives.class)).isEqualTo("interface Primitives {" +
3536
"aByte: number; " +
3637
"aShort: number; " +
37-
"int: number; " +
38-
"long: number; " +
39-
"float: number; " +
38+
"boolean: boolean; " +
4039
"double: number; " +
41-
"boolean: boolean;}");
40+
"float: number; " +
41+
"int: number; " +
42+
"long: number;}");
4243
}
4344

4445
@Test
4546
void wrapperTypes() {
4647
assertThat(converter.convert(WrapperTypes.class)).isEqualTo("interface WrapperTypes {" +
4748
"aByte: number; " +
4849
"aShort: number; " +
49-
"integer: number; " +
50-
"long: number; " +
5150
"boolean: boolean; " +
51+
"double?: number; " +
5252
"float?: number; " +
53-
"double?: number;}");
53+
"integer: number; " +
54+
"long: number;}");
5455
}
5556

5657
@Test
5758
void jsonProperty() {
5859
assertThat(converter.convert(JsonPropertyObject.class)).isEqualTo("interface JsonPropertyObject {" +
59-
"namedProperty: boolean; " +
60-
"literalObject: any;}");
60+
"literalObject: any; " +
61+
"namedProperty: boolean;" +
62+
"}");
6163
}
6264

6365
@Test
@@ -70,6 +72,7 @@ void realClass() {
7072
@Test
7173
void record() {
7274
assertThat(converter.convert(Record.class)).isEqualTo("interface Record {" +
75+
"isCool: boolean; " +
7376
"hello: string; " +
7477
"world: string;}");
7578
}
@@ -150,4 +153,4 @@ interface AnyId {
150153
Object getId();
151154
}
152155

153-
record Record(String hello, String world) {}
156+
record Record(String hello, String world, boolean isCool) {}

src/test/java/jvm2dts/ConverterTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ public class ConverterTest {
1313
@Test
1414
void collections() {
1515
assertThat(converter.convert(Collections.class)).isEqualTo("interface Collections {" +
16-
"roles: Role[]; " +
1716
"dates: string[]; " +
17+
"extendedGeneric: SingleGeneric<T>; " +
18+
"generic: MultiGeneric<T,U,V>; " +
19+
"genericRecursiveList: SingleGeneric[]; " +
1820
"ids: string[]; " +
1921
"map: {[key: string]: number}; " +
2022
"mapInMap: {[key: string]: {[key: string]: number}}; " +
21-
"extendedGeneric: SingleGeneric<T>; " +
23+
"rawType: ArrayList; " +
24+
"roles: Role[]; " +
2225
"superGeneric: SingleGeneric<T>; " +
23-
"generic: MultiGeneric<T,U,V>; " +
24-
"superGenericList: Role[]; " +
25-
"genericRecursiveList: SingleGeneric[]; " +
26-
"rawType: ArrayList;" +
26+
"superGenericList: Role[];" +
2727
"}");
2828
}
2929
}

0 commit comments

Comments
 (0)