Skip to content

Commit 519545d

Browse files
MaowcraftMaowcraft
Maowcraft
authored and
Maowcraft
committed
enhanced filtering
1 parent 399f01b commit 519545d

File tree

8 files changed

+164
-51
lines changed

8 files changed

+164
-51
lines changed

example-java-9/src/main/java/org/transparent/lucent/example/ExampleTranslator.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,21 @@
77
import com.sun.tools.javac.util.Name;
88
import com.sun.tools.javac.util.Names;
99
import org.transparent.lucent.transform.LucentTranslator;
10+
import org.transparent.lucent.transform.LucentValidator;
1011

1112
import javax.lang.model.element.Element;
1213

1314
public final class ExampleTranslator extends LucentTranslator {
14-
public ExampleTranslator(Names names, TreeMaker factory) {
15-
super(names, factory);
15+
public ExampleTranslator(Names names, TreeMaker factory, LucentValidator validator) {
16+
super(names, factory, validator);
1617
}
1718

1819
@Override
19-
public void translate(JCTree tree, Element element) {
20-
if (tree instanceof JCClassDecl) {
21-
final JCClassDecl clazz = (JCClassDecl) tree;
22-
clazz.defs = clazz.defs
23-
.append(field());
24-
result = clazz;
25-
}
20+
public void visitClassDef(JCClassDecl tree) {
21+
super.visitClassDef(tree);
22+
tree.defs = tree.defs
23+
.append(field());
24+
result = tree;
2625
}
2726

2827
private JCVariableDecl field() {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.transparent.lucent.example.test;
2+
3+
// This class isn't annotated, if the generated field appears on it,
4+
// it means that the annotated filtering doesn't work.
5+
public class Test2 {
6+
}

example/src/main/java/org/transparent/lucent/example/ExampleTranslator.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,21 @@
77
import com.sun.tools.javac.util.Name;
88
import com.sun.tools.javac.util.Names;
99
import org.transparent.lucent.transform.LucentTranslator;
10+
import org.transparent.lucent.transform.LucentValidator;
1011

1112
import javax.lang.model.element.Element;
1213

1314
public final class ExampleTranslator extends LucentTranslator {
14-
public ExampleTranslator(Names names, TreeMaker factory) {
15-
super(names, factory);
15+
public ExampleTranslator(Names names, TreeMaker factory, LucentValidator validator) {
16+
super(names, factory, validator);
1617
}
1718

1819
@Override
19-
public void translate(JCTree tree, Element element) {
20-
if (tree instanceof JCClassDecl) {
21-
final JCClassDecl clazz = (JCClassDecl) tree;
22-
clazz.defs = clazz.defs
23-
.append(field());
24-
result = clazz;
25-
}
20+
public void visitClassDef(JCClassDecl tree) {
21+
super.visitClassDef(tree);
22+
tree.defs = tree.defs
23+
.append(field());
24+
result = tree;
2625
}
2726

2827
private JCVariableDecl field() {

src/main/java/org/transparent/lucent/processor/LucentProcessor.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.sun.tools.javac.util.Names;
99
import org.transparent.lucent.transform.LucentTranslator;
1010
import org.transparent.lucent.transform.LucentValidator;
11+
import org.transparent.lucent.util.FilteringTranslator;
12+
import org.transparent.lucent.util.TriFunction;
1113
import org.transparent.lucent.util.TypeKind;
1214

1315
import javax.annotation.processing.AbstractProcessor;
@@ -19,17 +21,17 @@
1921
import javax.lang.model.element.ElementKind;
2022
import javax.lang.model.element.TypeElement;
2123
import java.lang.annotation.Annotation;
22-
import java.lang.reflect.Type;
2324
import java.util.*;
24-
import java.util.function.BiFunction;
2525
import java.util.stream.Collectors;
2626

27+
import static org.transparent.lucent.util.CollectionsUtil.*;
28+
2729
/**
2830
* A wrapper around {@link AbstractProcessor} that allows for cleaner AST modification.
2931
* <p>
3032
* This processor will process root elements,
3133
* skip the ones that aren't supported by the processor,
32-
* and invoke {@link LucentTranslator#translate(JCTree, Element)} on them.
34+
* and visit the root elements' trees via {@link JCTree#accept(JCTree.Visitor)}.
3335
* <p>
3436
* It is up to the associated {@link LucentTranslator}
3537
* specified by {@link #getTranslator()} to filter and transform trees obtained from
@@ -45,6 +47,7 @@
4547
public abstract class LucentProcessor extends AbstractProcessor {
4648
private final Set<TypeKind> kinds;
4749
private LucentTranslator translator;
50+
private LucentValidator validator;
4851

4952
protected Trees trees;
5053
protected Context context;
@@ -67,6 +70,7 @@ public synchronized void init(ProcessingEnvironment env) {
6770
factory = TreeMaker.instance(context);
6871
names = Names.instance(context);
6972
translator = getTranslator();
73+
validator = getValidator();
7074
}
7175

7276
/**
@@ -100,7 +104,8 @@ protected boolean process(RoundEnvironment env) {
100104
final JCTree tree = (JCTree) trees.getTree(element);
101105
preTranslate(tree, element, translator);
102106
if (translator != null)
103-
translator.translate(tree, element);
107+
new FilteringTranslator(getSupportedAnnotations(), translator)
108+
.filter(tree);
104109
postTranslate(tree, element, translator);
105110
}
106111
}
@@ -160,9 +165,7 @@ protected void postTranslate(JCTree tree, Element element, LucentTranslator tran
160165
* @return a set of supported type kinds
161166
*/
162167
public Set<TypeKind> getSupportedTypeKinds() {
163-
final Set<TypeKind> types = new HashSet<>();
164-
Collections.addAll(types, TypeKind.values());
165-
return types;
168+
return hashSetOf(TypeKind.values());
166169
}
167170

168171
/**
@@ -181,6 +184,17 @@ public LucentTranslator getTranslator() {
181184
return null;
182185
}
183186

187+
/**
188+
* Returns the validator associated with this processor.
189+
* <p>
190+
* An instance of this is passed to the translator.
191+
*
192+
* @return the associated {@link LucentValidator}
193+
*/
194+
public LucentValidator getValidator() {
195+
return null;
196+
}
197+
184198
/**
185199
* Returns an instance of {@link LucentTranslator} based on the fields of this processor.
186200
* <p>
@@ -191,9 +205,10 @@ public LucentTranslator getTranslator() {
191205
* @return an instance of {@code LucentTranslator}
192206
*/
193207
protected LucentTranslator translator(
194-
BiFunction<Names, TreeMaker,
208+
TriFunction<Names, TreeMaker,
209+
LucentValidator,
195210
LucentTranslator> constructor) {
196-
return constructor.apply(names, factory);
211+
return constructor.apply(names, factory, validator);
197212
}
198213

199214
/**

src/main/java/org/transparent/lucent/transform/LucentTranslator.java

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* These are usually instantiated by {@link LucentProcessor} and are called when a valid element
1717
* has been processed and is able to be transformed.
1818
* <p>
19-
* The processor's filtering is lightweight however, and as such, this class provides access to a
19+
* The processor's filtering is lightweight however, and as such, is provided access to a
2020
* {@link LucentValidator} which allows individual types of {@code JCTree}s to be validated based on the
2121
* implementation of the validator.
2222
*
@@ -37,31 +37,10 @@ public abstract class LucentTranslator extends TreeTranslator {
3737
* @param names an instance of {@code Names} that can be used to get instances of {@link Name}
3838
* @param factory an instance of {@code TreeMaker} that allows for transformation of trees
3939
*/
40-
public LucentTranslator(Names names, TreeMaker factory) {
41-
this.validator = getValidator();
40+
public LucentTranslator(Names names, TreeMaker factory, LucentValidator validator) {
4241
this.names = names;
4342
this.factory = factory;
43+
this.validator = validator;
4444
}
45-
46-
/**
47-
* Returns the validator associated with this translator.
48-
* <p>
49-
* If necessary, it's possible to use this to have
50-
* dynamic validation set up for your processor as the {@link #validator}
51-
* field of all translators is mutable.
52-
*
53-
* @return the associated {@link LucentValidator}
54-
*/
55-
protected LucentValidator getValidator() {
56-
return null;
57-
}
58-
59-
/**
60-
* Where the {@link JCTree} transformations occur.
61-
*
62-
* @param tree the target {@code JCTree}
63-
* @param element the {@link Element} associated with this tree
64-
*/
65-
public abstract void translate(JCTree tree, Element element);
6645
}
6746

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.transparent.lucent.util;
2+
3+
import java.util.Arrays;
4+
import java.util.HashSet;
5+
import java.util.LinkedHashSet;
6+
import java.util.Set;
7+
8+
public final class CollectionsUtil {
9+
private CollectionsUtil() {}
10+
11+
@SafeVarargs
12+
public static <T> Set<T> hashSetOf(T... elements) {
13+
return new HashSet<>(Arrays.asList(elements));
14+
}
15+
16+
@SafeVarargs
17+
public static <T> Set<T> linkedHashSetOf(T... elements) {
18+
return new LinkedHashSet<>(Arrays.asList(elements));
19+
}
20+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.transparent.lucent.util;
2+
3+
import com.sun.tools.javac.tree.JCTree;
4+
import com.sun.tools.javac.tree.JCTree.*;
5+
import com.sun.tools.javac.tree.TreeTranslator;
6+
import org.transparent.lucent.transform.LucentTranslator;
7+
8+
import java.lang.annotation.Annotation;
9+
import java.util.Set;
10+
import java.util.stream.Collectors;
11+
12+
/**
13+
* This implementation of a {@link TreeTranslator} stores a {@link LucentTranslator}
14+
* and filters through annotated elements so that manual filtering doesn't need to be done.
15+
*
16+
* @author Maow
17+
* @version %I%
18+
* @since 1.0.0
19+
*/
20+
// TODO: Document methods
21+
public final class FilteringTranslator extends TreeTranslator {
22+
private final Set<String> annotations;
23+
private final LucentTranslator translator;
24+
25+
public FilteringTranslator(
26+
Set<Class<? extends Annotation>> annotations,
27+
LucentTranslator translator) {
28+
this.annotations = annotations
29+
.stream()
30+
.map(Class::getCanonicalName)
31+
.collect(Collectors.toSet());
32+
this.translator = translator;
33+
}
34+
35+
public void filter(JCTree tree) {
36+
if (tree instanceof JCClassDecl) {
37+
final JCClassDecl clazz = (JCClassDecl) tree;
38+
filterClass(clazz);
39+
for (JCTree def : clazz.defs)
40+
filterMember(def);
41+
}
42+
}
43+
44+
private void filterClass(JCClassDecl clazz) {
45+
if (isAnnotated(clazz))
46+
clazz.accept(translator);
47+
}
48+
49+
private void filterMember(JCTree tree) {
50+
if (isAnnotated(tree))
51+
tree.accept(translator);
52+
}
53+
54+
private boolean isAnnotated(JCTree tree) {
55+
JCModifiers mods = null;
56+
if (tree instanceof JCClassDecl)
57+
mods = ((JCClassDecl) tree).mods;
58+
else if (tree instanceof JCVariableDecl)
59+
mods = ((JCVariableDecl) tree).mods;
60+
else if (tree instanceof JCMethodDecl)
61+
mods = ((JCMethodDecl) tree).mods;
62+
if (mods != null) return isAnnotated(mods);
63+
return false;
64+
}
65+
66+
private boolean isAnnotated(JCModifiers mods) {
67+
if (mods.annotations.isEmpty()) return false;
68+
return mods.annotations.stream().anyMatch(annotation ->
69+
annotations.contains(
70+
annotation.type.tsym
71+
.getQualifiedName()
72+
.toString()
73+
));
74+
}
75+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.transparent.lucent.util;
2+
3+
import java.util.function.Function;
4+
5+
/**
6+
* A functional interface returning a type from three parameters.
7+
*
8+
* @author Maow
9+
* @version %I%
10+
* @param <T> first parameter
11+
* @param <U> second parameter
12+
* @param <V> third parameter
13+
* @param <W> type to return
14+
* @see Function
15+
* @since 1.0.0
16+
*/
17+
@FunctionalInterface
18+
public interface TriFunction<T, U, V, W> {
19+
W apply(T t, U u, V v);
20+
}

0 commit comments

Comments
 (0)