Skip to content

Commit 75955f5

Browse files
feat: add module[spring-boot-annotationProcessor]
1 parent dc87e8d commit 75955f5

File tree

6 files changed

+171
-2
lines changed

6 files changed

+171
-2
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
dependencyManagement {
2+
imports {
3+
mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}"
4+
}
5+
}
6+
7+
dependencies {
8+
annotationProcessor project(":spring-boot-annotationProcessor")
9+
testAnnotationProcessor project(":spring-boot-annotationProcessor")
10+
implementation(files("${System.properties['java.home']}/../lib/tools.jar"))
11+
12+
testImplementation('com.google.testing.compile:compile-testing:0.19')
13+
testImplementation("org.springframework.boot:spring-boot-starter-test")
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.ooooo.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* @author <a href="https://github.com/ooooo-youwillsee">ooooo</a>
10+
* @since 1.0.0
11+
*/
12+
@Target({ElementType.FIELD, ElementType.TYPE})
13+
@Retention(RetentionPolicy.SOURCE)
14+
public @interface MyGetter {
15+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package com.ooooo.annotation;
2+
3+
import com.sun.source.util.Trees;
4+
import com.sun.tools.javac.code.Flags;
5+
import com.sun.tools.javac.code.TypeTag;
6+
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
7+
import com.sun.tools.javac.processing.PrintingProcessor;
8+
import com.sun.tools.javac.tree.JCTree.JCBlock;
9+
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
10+
import com.sun.tools.javac.tree.JCTree.JCExpression;
11+
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
12+
import com.sun.tools.javac.tree.JCTree.JCModifiers;
13+
import com.sun.tools.javac.tree.JCTree.JCStatement;
14+
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
15+
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
16+
import com.sun.tools.javac.tree.TreeMaker;
17+
import com.sun.tools.javac.util.Context;
18+
import com.sun.tools.javac.util.List;
19+
import com.sun.tools.javac.util.Name;
20+
import com.sun.tools.javac.util.Names;
21+
import com.sun.tools.javac.util.UnsharedNameTable;
22+
import java.util.Set;
23+
import javax.annotation.processing.AbstractProcessor;
24+
import javax.annotation.processing.ProcessingEnvironment;
25+
import javax.annotation.processing.RoundEnvironment;
26+
import javax.annotation.processing.SupportedAnnotationTypes;
27+
import javax.lang.model.element.Element;
28+
import javax.lang.model.element.TypeElement;
29+
import javax.lang.model.util.SimpleElementVisitor8;
30+
31+
/**
32+
* @author <a href="https://github.com/ooooo-youwillsee">ooooo</a>
33+
* @see PrintingProcessor
34+
* @see SimpleElementVisitor8
35+
* @since 1.0.0
36+
*/
37+
// todo javac source code
38+
@SupportedAnnotationTypes("com.ooooo.annotation.MyGetter")
39+
public class MyGetterAnnotationProcessor extends AbstractProcessor {
40+
41+
private Trees mTrees;
42+
private TreeMaker mTreeMaker;
43+
44+
45+
@Override
46+
public synchronized void init(ProcessingEnvironment processingEnv) {
47+
mTreeMaker = TreeMaker.instance(((JavacProcessingEnvironment) processingEnv).getContext());
48+
mTrees = Trees.instance(processingEnv);
49+
super.init(processingEnv);
50+
}
51+
52+
@Override
53+
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
54+
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(MyGetter.class);
55+
56+
for (Element element : elements) {
57+
JCClassDecl classDecl = (JCClassDecl) mTrees.getTree(element);
58+
addGetterMethod(element, classDecl);
59+
}
60+
61+
return true;
62+
}
63+
64+
private void addGetterMethod(Element element, JCClassDecl classDecl) {
65+
Name methodName = getName("get");
66+
JCBlock methodBody = getMethodBody();
67+
JCModifiers modifiers = mTreeMaker.Modifiers(Flags.PUBLIC);
68+
JCExpression returnType = mTreeMaker.TypeIdent(TypeTag.VOID);
69+
List<JCVariableDecl> parameters = List.nil();
70+
List<JCTypeParameter> generics = List.nil();
71+
List<JCExpression> throwz = List.nil();
72+
73+
JCMethodDecl methodDecl = mTreeMaker.MethodDef(modifiers, methodName, returnType, generics, parameters, throwz, methodBody, null);
74+
75+
classDecl.defs = classDecl.defs.append(methodDecl);
76+
77+
// JCExpression importExpression = mTreeMaker.Ident(getName("com"));
78+
// importExpression = mTreeMaker.Select(importExpression, getName("ooooo"));
79+
// importExpression = mTreeMaker.Select(importExpression, getName("annotation"));
80+
// importExpression = mTreeMaker.Select(importExpression, getName("MyGetter"));
81+
//
82+
// JCImport importDel = mTreeMaker.Import(importExpression, false);
83+
84+
// classDecl.defs = classDecl.defs.prepend(importDel);
85+
86+
System.out.println("classDel:\n" + classDecl);
87+
}
88+
89+
private JCBlock getMethodBody() {
90+
JCExpression printExpression = mTreeMaker.Ident(getName("System"));
91+
printExpression = mTreeMaker.Select(printExpression, getName("out"));
92+
printExpression = mTreeMaker.Select(printExpression, getName("println"));
93+
94+
List<JCExpression> printArgs = List.from(new JCExpression[]{mTreeMaker.Literal("Hello from HelloProcessor!")});
95+
96+
printExpression = mTreeMaker.Apply(List.nil(), printExpression, printArgs);
97+
98+
JCStatement call = mTreeMaker.Exec(printExpression);
99+
100+
List<JCStatement> statements = List.from(new JCStatement[]{call});
101+
102+
return mTreeMaker.Block(0, statements);
103+
}
104+
105+
private Name getName(String name) {
106+
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
107+
Names names = new Names(context);
108+
return UnsharedNameTable.create(names).fromString(name);
109+
}
110+
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.ooooo.annotation.MyGetterAnnotationProcessor
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import com.ooooo.annotation.MyGetter;
2+
3+
/**
4+
* @author <a href="https://github.com/ooooo-youwillsee">ooooo</a>
5+
* @since 1.0.0
6+
*/
7+
@MyGetter
8+
public class User {
9+
10+
private String username;
11+
12+
private Integer age;
13+
}
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
package com.ooooo.annotation;
22

3+
import static com.google.testing.compile.CompilationSubject.assertThat;
4+
import static com.google.testing.compile.Compiler.javac;
5+
6+
import com.google.testing.compile.Compilation;
7+
import com.google.testing.compile.JavaFileObjects;
8+
import org.junit.jupiter.api.Test;
9+
310
/**
411
* @author <a href="https://github.com/ooooo-youwillsee">ooooo</a>
512
* @since 1.0.0
613
*/
714
class MyGetterAnnotationProcessorTest {
815

9-
public static void main(String[] args) {
10-
User user = new User();
16+
@Test
17+
void test() {
18+
Compilation compilation = javac()
19+
.withProcessors(new MyGetterAnnotationProcessor())
20+
.compile(JavaFileObjects.forResource("User.java"));
21+
22+
assertThat(compilation).succeeded();
23+
// assertThat(compilation)
24+
// .generatedSourceFile("GeneratedHelloWorld")
25+
// .hasSourceEquivalentTo(JavaFileObjects.forResource("GeneratedHelloWorld.java"));
1126
}
1227
}

0 commit comments

Comments
 (0)