blob: 18f9ed632053e7078d89f5b57a57f2c135e14381 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
package ftbsc.lll.processor.tools;
import com.squareup.javapoet.*;
import ftbsc.lll.tools.DescriptorBuilder;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.function.Function;
import static ftbsc.lll.processor.tools.ASTUtils.classArrayFromAnnotation;
/**
* Collection of static utils that rely on JavaPoet to function.
*/
public class JavaPoetUtils {
/**
* Builds a {@link MethodSpec} for a public method whose body simply returns a {@link String}.
* @param name the name of the method
* @param returnString the {@link String} to return
* @return the built {@link MethodSpec}
*/
public static MethodSpec buildStringReturnMethod(String name, String returnString) {
return MethodSpec.methodBuilder(name)
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
.returns(String.class)
.addStatement("return $S", returnString)
.build();
}
/**
* Builds a type descriptor from the given {@link TypeName}.
* @param type the {@link TypeName} representing the desired type
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromType(TypeName type) {
StringBuilder desc = new StringBuilder();
//add array brackets
while(type instanceof ArrayTypeName) {
desc.append("[");
type = ((ArrayTypeName) type).componentType;
}
if(type instanceof ClassName || type instanceof ParameterizedTypeName) {
ClassName var = type instanceof ParameterizedTypeName ? ((ParameterizedTypeName) type).rawType : (ClassName) type;
desc.append(DescriptorBuilder.nameToDescriptor(var.canonicalName(), 0));
} else {
if(TypeName.BOOLEAN.equals(type))
desc.append("Z");
else if(TypeName.CHAR.equals(type))
desc.append("C");
else if(TypeName.BYTE.equals(type))
desc.append("B");
else if(TypeName.SHORT.equals(type))
desc.append("S");
else if(TypeName.INT.equals(type))
desc.append("I");
else if(TypeName.FLOAT.equals(type))
desc.append("F");
else if(TypeName.LONG.equals(type))
desc.append("J");
else if(TypeName.DOUBLE.equals(type))
desc.append("D");
else if(TypeName.VOID.equals(type))
desc.append("V");
}
return desc.toString();
}
/**
* Builds a type descriptor from the given {@link TypeMirror}.
* @param t the {@link TypeMirror} representing the desired type
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromType(TypeMirror t) {
return descriptorFromType(TypeName.get(t));
}
/**
* Builds a method descriptor from the given {@link ExecutableElement}.
* @param m the {@link ExecutableElement} for the method
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromExecutableElement(ExecutableElement m) {
StringBuilder methodSignature = new StringBuilder();
methodSignature.append("(");
m.getParameters().forEach(p -> methodSignature.append(descriptorFromType(p.asType())));
methodSignature.append(")");
methodSignature.append(descriptorFromType(m.getReturnType()));
return methodSignature.toString();
}
/**
* Builds a (partial, not including the return type) method descriptor from its parameters
* @param ann the annotation containing the class
* @param fun the annotation function returning the class
* @return the method descriptor
*/
public static <T extends Annotation> String methodDescriptorFromParams(T ann, Function<T, Class<?>[]> fun, Elements elementUtils) {
List<TypeMirror> mirrors = classArrayFromAnnotation(ann, fun, elementUtils);
StringBuilder sb = new StringBuilder("(");
for(TypeMirror t : mirrors)
sb.append(descriptorFromType(t));
sb.append(")");
return sb.toString();
}
}
|