/
Encodings.java
112 lines (95 loc) · 3.34 KB
/
Encodings.java
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
111
112
package org.immutables.value.processor.encode;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import org.immutables.generator.AbstractTemplate;
import org.immutables.generator.Generator;
import org.immutables.generator.Naming;
import org.immutables.generator.SourceExtraction;
import org.immutables.generator.Templates;
import org.immutables.value.processor.meta.Reporter;
@Generator.Template
public abstract class Encodings extends AbstractTemplate {
@Generator.Typedef
Encoding Encoding;
public abstract Templates.Invokable generate();
final Reporter reporter = Reporter.from(processing());
final List<Encoding> encodings = new ArrayList<>();
Encodings() {
for (TypeElement a : annotations()) {
for (TypeElement t : ElementFilter.typesIn(round().getElementsAnnotatedWith(a))) {
encodings.add(new Encoding(t));
}
}
}
class Encoding {
private final CharSequence source;
private final Type.Factory types = new Type.Producer();
private final TypeExtractor typesReader;
private Object impl;
Encoding(TypeElement type) {
if (type.getKind() != ElementKind.CLASS || type.getNestingKind() != NestingKind.TOP_LEVEL) {
reporter.withElement(type).error("Encoding type '%s' should be top-level class", type.getSimpleName());
}
source = SourceExtraction.extract(processing(), type);
if (source.length() == 0) {
reporter.withElement(type)
.error("No source code can be extracted for @Encoding class. Unsupported compilation mode");
}
this.typesReader = new TypeExtractor(types, type);
for (Element e : type.getEnclosedElements()) {
processMember(e);
}
}
private void processMember(Element member) {
if (member.getKind() == ElementKind.FIELD) {
if (processField((VariableElement) member)) return;
}
if (member.getKind() == ElementKind.METHOD) {
if (processMethod((ExecutableElement) member)) return;
}
if (member.getKind() == ElementKind.CLASS) {
if (processClass((TypeElement) member)) return;
}
reporter.withElement(member)
.warning("Unrecognized element '%s' will be ignored", member.getSimpleName());
}
private boolean processMethod(ExecutableElement method) {
return false;
}
private boolean processField(VariableElement field) {
if (ImplMirror.isPresent(field)) {
if (impl != null) {
reporter.withElement(field).error(
"@Encoding.Impl duplicate field '%s' cannot have more than one implementation field",
field.getSimpleName());
return true;
}
if (field.getModifiers().contains(Modifier.STATIC)) {
reporter.withElement(field).error(
"@Encoding.Impl field '%s' cannot be static",
field.getSimpleName());
return true;
}
new EncodedElement.Builder()
.name(field.getSimpleName().toString())
.type(typesReader.get(field.asType()))
.naming(Naming.identity())
.build();
}
return false;
}
private boolean processClass(TypeElement type) {
if (type.getSimpleName().contentEquals("Builder")) {
}
return false;
}
}
}