Skip to content

Commit 213c383

Browse files
committed
refactor(code): add transformer plugin
1 parent c8f79b6 commit 213c383

20 files changed

+647
-610
lines changed

archetype/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.bsc.processor</groupId>
77
<artifactId>java2ts-processor-parent</artifactId>
8-
<version>1.3.1</version>
8+
<version>1.4-SNAPSHOT</version>
99
</parent>
1010
<artifactId>java2ts-processor-archetype</artifactId>
1111
<name>java2ts-processor::archetype</name>

core/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>org.bsc.processor</groupId>
66
<artifactId>java2ts-processor-parent</artifactId>
7-
<version>1.3.1</version>
7+
<version>1.4-SNAPSHOT</version>
88
</parent>
99
<artifactId>java2ts-processor-core</artifactId>
1010
<name>java2ts-processor::core</name>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package org.bsc.java2typescript;
2+
3+
import org.bsc.java2typescript.transformer.TSJavaClass2DeclarationTransformer;
4+
import org.bsc.java2typescript.transformer.TSJavaClass2StaticDefinitionTransformer;
5+
6+
import java.lang.reflect.Executable;
7+
import java.lang.reflect.Method;
8+
import java.lang.reflect.Modifier;
9+
import java.util.Comparator;
10+
import java.util.Optional;
11+
import java.util.stream.Collectors;
12+
import java.util.stream.Stream;
13+
14+
import static java.lang.String.format;
15+
16+
/**
17+
* @author bsorrentino
18+
*/
19+
public class TSConverter extends TSConverterStatic {
20+
public enum Compatibility {
21+
NASHORN, RHINO, GRAALJS;
22+
23+
public String javaType(String fqn) {
24+
switch (this.ordinal()) {
25+
case 1:
26+
return format("Packages.%s", fqn);
27+
default:
28+
return format("Java.type(\"%s\")", fqn);
29+
}
30+
}
31+
}
32+
33+
final Compatibility compatibility;
34+
35+
public TSConverter(Compatibility compatibility) {
36+
super();
37+
this.compatibility = compatibility;
38+
}
39+
40+
/**
41+
* @return
42+
*/
43+
public final boolean isRhino() {
44+
return compatibility == Compatibility.RHINO;
45+
}
46+
47+
/**
48+
* @param type
49+
* @param declaredTypeMap
50+
* @return
51+
*/
52+
public String processStatic(TSType type, java.util.Map<String, TSType> declaredTypeMap) {
53+
54+
final TSConverterContext ctx = TSConverterContext.of(type, declaredTypeMap, compatibility);
55+
56+
final TSJavaClass2StaticDefinitionTransformer transformer = new TSJavaClass2StaticDefinitionTransformer();
57+
58+
return transformer.apply(ctx).toString();
59+
}
60+
61+
/**
62+
* @param m
63+
* @param type
64+
* @param declaredTypeMap
65+
* @param packageResolution
66+
* @return
67+
*/
68+
public <E extends Executable> String getMethodParametersAndReturnDecl(E m, TSType type,
69+
java.util.Map<String, TSType> declaredTypeMap, boolean packageResolution) {
70+
71+
return TSConverterContext.of(type, declaredTypeMap, compatibility)
72+
.getMethodParametersAndReturnDecl(m, packageResolution);
73+
}
74+
75+
76+
/**
77+
* @param level
78+
* @param tstype
79+
* @param declaredTypeMap
80+
* @return
81+
*/
82+
public String processClass(int level, TSType tstype, java.util.Map<String, TSType> declaredTypeMap) {
83+
84+
final TSConverterContext ctx = TSConverterContext.of(tstype, declaredTypeMap, compatibility);
85+
86+
final TSJavaClass2DeclarationTransformer transformer = new TSJavaClass2DeclarationTransformer();
87+
88+
return transformer.apply(ctx).toString();
89+
90+
}
91+
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
package org.bsc.java2typescript;
2+
3+
import java.lang.reflect.*;
4+
import java.util.Arrays;
5+
import java.util.Map;
6+
import java.util.Objects;
7+
import java.util.Optional;
8+
import java.util.function.Consumer;
9+
import java.util.stream.Collectors;
10+
11+
public class TSConverterContext extends TSConverterStatic implements Cloneable {
12+
public final TSType type;
13+
public final java.util.Map<String, TSType> declaredTypeMap;
14+
public final TSConverter.Compatibility compatibility;
15+
final StringBuilder sb = new StringBuilder();
16+
17+
/**
18+
* @param tstype
19+
* @param declaredTypeMap
20+
* @return
21+
*/
22+
public static TSConverterContext of(TSType tstype,
23+
java.util.Map<String, TSType> declaredTypeMap,
24+
TSConverter.Compatibility compatibility) {
25+
return new TSConverterContext(tstype, declaredTypeMap, compatibility);
26+
}
27+
28+
29+
private TSConverterContext(TSType type, Map<String, TSType> declaredClassMap, TSConverter.Compatibility compatibility) {
30+
Objects.requireNonNull(type, "type is null!");
31+
Objects.requireNonNull(declaredClassMap, "declaredClassMap is null!");
32+
33+
this.type = type;
34+
this.declaredTypeMap = declaredClassMap;
35+
this.compatibility = compatibility;
36+
}
37+
38+
/**
39+
* @param cs
40+
* @return
41+
*/
42+
public TSConverterContext append(CharSequence cs) {
43+
sb.append(cs);
44+
return this;
45+
}
46+
47+
/**
48+
* @param ch
49+
* @return
50+
*/
51+
public TSConverterContext append(char ch) {
52+
sb.append(ch);
53+
return this;
54+
}
55+
56+
/**
57+
* @return
58+
*/
59+
public TSConverterContext getClassDecl() {
60+
61+
final StringBuilder inherited = new StringBuilder();
62+
63+
if (type.getValue().isInterface()) {
64+
sb.append("interface ");
65+
} else {
66+
67+
if (type.getValue().isEnum())
68+
sb.append("/* enum */");
69+
70+
if (type.hasAlias())
71+
sb.append("declare ");
72+
73+
sb.append("class ");
74+
75+
final TSType superclass = TSType.of(type.getValue().getSuperclass());
76+
77+
if (superclass != null) {
78+
inherited.append(" extends ").append(getTypeName(superclass, type, true));
79+
}
80+
}
81+
82+
final Class<?>[] interfaces = type.getValue().getInterfaces();
83+
84+
if (interfaces.length > 0) {
85+
86+
final String ifc = Arrays.stream(interfaces).map(c -> TSType.of(c))
87+
.map(t -> getTypeName(t, type, true)).collect(Collectors.joining(", "));
88+
inherited.append((type.getValue().isInterface()) ? " extends " : " implements ").append(ifc);
89+
90+
}
91+
92+
sb.append(getTypeName(type, type, true));
93+
94+
if (inherited.length() > 0 || type.hasAlias()) {
95+
96+
sb.append("/*");
97+
98+
if (type.hasAlias())
99+
sb.append(type.getValue().getName());
100+
if (inherited.length() > 0)
101+
sb.append(inherited);
102+
103+
sb.append("*/");
104+
}
105+
106+
sb.append(" {");
107+
108+
return this;
109+
}
110+
111+
/**
112+
* @return
113+
*/
114+
public TSConverterContext processEnumDecl() {
115+
if (type.getValue().isEnum()) {
116+
type.setExport(true); // force export
117+
// fix #4
118+
// Arrays.stream(type.getValue().getEnumConstants())
119+
Arrays.stream(type.getValue().getFields())
120+
.filter(f -> f.isEnumConstant())
121+
.forEach((c) -> sb.append('\t')
122+
.append("// ")
123+
.append(c.getName())
124+
.append(':')
125+
.append(type.getSimpleTypeName())
126+
.append(';')
127+
.append('\n'));
128+
sb.append('\n');
129+
}
130+
131+
return this;
132+
133+
}
134+
135+
/**
136+
* @param
137+
* @return Context processMemberClasses(int level) {
138+
* <p>
139+
* final Class<?> memberClasses[] = type.getValue().getClasses();
140+
* <p>
141+
* if (memberClasses.length == 0)
142+
* return this;
143+
* <p>
144+
* // sb.append( "export module " )
145+
* // .append(type.getSimpleTypeName())
146+
* // .append(" {\n\n")
147+
* // ;
148+
* <p>
149+
* Stream.of(memberClasses).peek(c -> debug("nested class name[%s]", c.getName()))
150+
* // .filter(distinctByKey( c -> c.getSimpleName() ))
151+
* .filter(distinctByKey(c -> c.getName())).map(cl -> TSType.of(cl))
152+
* .peek(t -> debug("nested type name[%s]", t.getTypeName()))
153+
* .map(t -> processClass(level + 1, t, declaredTypeMap))
154+
* .forEach(decl -> sb.append(decl));
155+
* <p>
156+
* // sb.append("\n} // end module ")
157+
* // .append(type.getSimpleTypeName())
158+
* // .append('\n')
159+
* // ;
160+
* return this;
161+
* }
162+
*/
163+
164+
public TSConverterContext processEnumType() {
165+
166+
// fix #4
167+
// Arrays.stream(type.getValue().getEnumConstants())
168+
Arrays.stream(type.getValue().getFields())
169+
.filter(f -> f.isEnumConstant())
170+
.forEach((c) -> sb.append('\t')
171+
.append(c.getName())
172+
.append(':')
173+
.append(type.getTypeName())
174+
.append(';')
175+
.append('\n'));
176+
sb.append('\n');
177+
178+
return this;
179+
180+
}
181+
182+
public <E extends Executable> String getMethodParametersAndReturnDecl(E m,
183+
boolean packageResolution) {
184+
final java.util.Set<String> TypeVarSet = new java.util.HashSet<>(5);
185+
186+
final Consumer<TypeVariable<?>> addTypeVar = tv -> TypeVarSet.add(tv.getName());
187+
188+
final Parameter[] params = m.getParameters();
189+
190+
final String params_string = Arrays.stream(params).map((tp) -> {
191+
192+
final String name = getParameterName(tp);
193+
194+
if (tp.isVarArgs()) {
195+
196+
String typeName = null;
197+
if (tp.getParameterizedType() instanceof GenericArrayType) {
198+
199+
typeName = convertJavaToTS(((GenericArrayType) tp.getParameterizedType()).getGenericComponentType(), m,
200+
type, declaredTypeMap, packageResolution, Optional.of(addTypeVar));
201+
} else {
202+
typeName = convertJavaToTS(tp.getType().getComponentType(), m, type, declaredTypeMap,
203+
packageResolution, Optional.of(addTypeVar));
204+
}
205+
return String.format("...%s:%s[]", name, typeName);
206+
207+
}
208+
209+
final String typeName = convertJavaToTS(tp.getParameterizedType(), m, type, declaredTypeMap,
210+
packageResolution, Optional.of(addTypeVar));
211+
return String.format("%s:%s", name, typeName);
212+
}).collect(Collectors.joining(", "));
213+
214+
final Type returnType = (m instanceof Method) ? ((Method) m).getGenericReturnType() : type.getValue();
215+
216+
final String tsReturnType = convertJavaToTS(returnType, m, type, declaredTypeMap, packageResolution,
217+
Optional.of(addTypeVar));
218+
219+
final StringBuilder result = new StringBuilder();
220+
221+
if (!TypeVarSet.isEmpty()) {
222+
result.append('<').append(TypeVarSet.stream().collect(Collectors.joining(","))).append('>');
223+
}
224+
return result.append("( ").append(params_string).append(" ):").append(tsReturnType).toString();
225+
}
226+
227+
public String getMethodDecl(final Method m, boolean optional) {
228+
229+
final StringBuilder sb = new StringBuilder();
230+
231+
if (Modifier.isStatic(m.getModifiers())) {
232+
233+
if (type.getValue().isInterface()) {
234+
sb.append("// ");
235+
}
236+
237+
sb.append("static ").append(m.getName());
238+
} else {
239+
sb.append(m.getName());
240+
if (optional)
241+
sb.append('?');
242+
}
243+
244+
sb.append(getMethodParametersAndReturnDecl(m, true));
245+
246+
return sb.toString();
247+
248+
}
249+
250+
/**
251+
*
252+
* @return
253+
*/
254+
public TSConverterContext clone() {
255+
256+
return new TSConverterContext(type, declaredTypeMap, compatibility);
257+
}
258+
259+
/**
260+
*
261+
*/
262+
@Override
263+
public String toString() {
264+
return sb.toString();
265+
}
266+
267+
} // end Context
268+
269+

0 commit comments

Comments
 (0)