22
33import com .sun .source .tree .Tree ;
44import com .sun .source .util .Trees ;
5+ import com .sun .tools .javac .code .Flags ;
6+ import com .sun .tools .javac .code .Symbol ;
7+ import com .sun .tools .javac .code .Type ;
58import com .sun .tools .javac .tree .JCTree ;
9+ import com .sun .tools .javac .tree .TreeMaker ;
10+ import com .sun .tools .javac .util .List ;
11+ import com .sun .tools .javac .util .Name ;
612import io .moyada .feign .help .annotation .FallbackBuild ;
713import io .moyada .feign .help .annotation .FallbackFactoryBuild ;
814import io .moyada .feign .help .support .SyntaxTreeMaker ;
1117import javax .lang .model .element .Element ;
1218import javax .lang .model .element .ElementKind ;
1319import java .util .ArrayList ;
20+ import java .util .Collection ;
1421import java .util .Collections ;
15- import java .util .List ;
1622import java .util .Set ;
1723
1824/**
@@ -25,12 +31,12 @@ public final class ElementUtil {
2531 private ElementUtil () {
2632 }
2733
28- public static List <JCTree .JCClassDecl > getFallbackFactory (Trees trees , RoundEnvironment roundEnv ) {
34+ public static Collection <JCTree .JCClassDecl > getFallbackFactory (Trees trees , RoundEnvironment roundEnv ) {
2935 Set <? extends Element > factoryEles = roundEnv .getElementsAnnotatedWith (FallbackFactoryBuild .class );
3036 if (factoryEles .isEmpty ()) {
3137 return Collections .emptyList ();
3238 }
33- List <JCTree .JCClassDecl > list = new ArrayList <JCTree .JCClassDecl >(factoryEles .size ());
39+ java . util . List <JCTree .JCClassDecl > list = new java . util . ArrayList <JCTree .JCClassDecl >(factoryEles .size ());
3440 for (Element element : factoryEles ) {
3541 if (element .getKind () == ElementKind .INTERFACE ) {
3642 JCTree .JCClassDecl classDecl = (JCTree .JCClassDecl ) trees .getTree (element );
@@ -40,13 +46,13 @@ public static List<JCTree.JCClassDecl> getFallbackFactory(Trees trees, RoundEnvi
4046 return list ;
4147 }
4248
43- public static List <JCTree .JCClassDecl > getFallback (Trees trees , RoundEnvironment roundEnv , List <JCTree .JCClassDecl > factoryEles ) {
49+ public static Collection <JCTree .JCClassDecl > getFallback (Trees trees , RoundEnvironment roundEnv , Collection <JCTree .JCClassDecl > factoryEles ) {
4450 Set <? extends Element > fallbackEles = roundEnv .getElementsAnnotatedWith (FallbackBuild .class );
4551 if (fallbackEles .isEmpty ()) {
4652 return factoryEles ;
4753 }
4854
49- List <JCTree .JCClassDecl > list = new ArrayList <JCTree .JCClassDecl >(fallbackEles .size ());
55+ Collection <JCTree .JCClassDecl > list = new java . util . ArrayList <JCTree .JCClassDecl >(fallbackEles .size ());
5056
5157 for (Element element : fallbackEles ) {
5258 if (element .getKind () == ElementKind .INTERFACE ) {
@@ -62,40 +68,114 @@ public static List<JCTree.JCClassDecl> getFallback(Trees trees, RoundEnvironment
6268 return list ;
6369 }
6470
65- public static List <JCTree .JCMethodDecl > getStaticMethod (Trees trees , SyntaxTreeMaker treeMaker , JCTree .JCClassDecl element ) {
66- List <JCTree .JCMethodDecl > list = new ArrayList <JCTree .JCMethodDecl >();
67-
71+ public static Collection <JCTree .JCMethodDecl > getStaticMethod (Trees trees , SyntaxTreeMaker treeMaker , JCTree .JCClassDecl element ) {
72+ Collection <JCTree .JCMethodDecl > list = new ArrayList <JCTree .JCMethodDecl >();
73+ // 获取目标类中方法
6874 if (element .defs != null ) {
6975 for (JCTree tree : element .defs ) {
7076 if (tree .getKind () == Tree .Kind .METHOD ) {
7177 list .add ((JCTree .JCMethodDecl ) tree );
7278 }
7379 }
7480 }
75-
81+ // 注入父类方法
7682 addSuperStaticMethod (list , trees , treeMaker , element );
7783 return list ;
7884 }
7985
80- private static void addSuperStaticMethod (List <JCTree .JCMethodDecl > list , Trees trees , SyntaxTreeMaker treeMaker , JCTree .JCClassDecl element ) {
86+ private static void addSuperStaticMethod (Collection <JCTree .JCMethodDecl > list , Trees trees , SyntaxTreeMaker treeMaker , JCTree .JCClassDecl element ) {
8187 if (element .implementing == null ) {
8288 return ;
8389 }
8490
91+ // 遍历继承接口
8592 for (JCTree .JCExpression imple : element .implementing ) {
8693 JCTree .JCIdent ident = (JCTree .JCIdent ) imple .getTree ();
94+
95+ // 获取当前类节点
8796 JCTree .JCClassDecl sup = (JCTree .JCClassDecl ) trees .getTree (ident .sym );
97+ if (sup == null ) {
98+ // 当前类中方法
99+ for (Symbol symbol : ident .sym .getEnclosedElements ()) {
100+ if (symbol .getKind () == ElementKind .METHOD ) {
101+ Symbol .MethodSymbol methodSymbol = (Symbol .MethodSymbol ) symbol ;
102+ JCTree .JCMethodDecl methodDecl = buildFHMethodDecl (treeMaker , methodSymbol );
103+ list .add (methodDecl );
104+ }
105+ }
106+ continue ;
107+ }
108+
109+ // 获取节点属性
110+ if (sup .defs != null ) {
111+ for (JCTree tree : sup .defs ) {
112+ if (tree .getKind () == Tree .Kind .METHOD ) {
113+ list .add ((JCTree .JCMethodDecl ) tree );
114+ }
115+ }
116+ }
88117
89118 // get super method
90119 addSuperStaticMethod (list , trees , treeMaker , sup );
91- if (sup .defs == null ) {
92- continue ;
120+ }
121+ }
122+
123+ private static JCTree .JCMethodDecl buildFHMethodDecl (SyntaxTreeMaker syntaxTreeMaker , Symbol .MethodSymbol symbol ) {
124+ TreeMaker treeMaker = syntaxTreeMaker .getTreeMaker ();
125+
126+ JCTree .JCModifiers mod = treeMaker .Modifiers (Flags .PUBLIC );
127+
128+ Name name = symbol .name ;
129+
130+ Type returnType = symbol .getReturnType ();
131+ JCTree .JCIdent restype = treeMaker .Ident (returnType .tsym );
132+
133+ List <JCTree .JCTypeParameter > typarams = null ;
134+ List <Symbol .TypeVariableSymbol > typeParameters = symbol .getTypeParameters ();
135+ if (typeParameters == null || typeParameters .isEmpty ()) {
136+ typarams = List .nil ();
137+ } else {
138+ for (Symbol .TypeVariableSymbol typeParameter : typeParameters ) {
139+ JCTree .JCTypeParameter jcTypeParameter = treeMaker .TypeParam (typeParameter .name , (Type .TypeVar ) typeParameter .type );
140+
141+ if (typarams == null ) {
142+ typarams = List .of (jcTypeParameter );
143+ } else {
144+ typarams = typarams .append (jcTypeParameter );
145+ }
93146 }
94- for (JCTree tree : sup .defs ) {
95- if (tree .getKind () == Tree .Kind .METHOD ) {
96- list .add ((JCTree .JCMethodDecl ) tree );
147+ }
148+
149+ List <JCTree .JCVariableDecl > params = null ;
150+ List <Symbol .VarSymbol > parameters = symbol .getParameters ();
151+ if (parameters == null || parameters .isEmpty ()) {
152+ params = List .nil ();
153+ } else {
154+ for (Symbol .VarSymbol parameter : parameters ) {
155+ JCTree .JCVariableDecl param = treeMaker .Param (parameter .name , parameter .type , parameter .owner );
156+ if (params == null ) {
157+ params = List .of (param );
158+ } else {
159+ params = params .append (param );
97160 }
98161 }
99162 }
163+
164+ List <JCTree .JCExpression > thrown = null ;
165+ List <Type > thrownTypes = symbol .getThrownTypes ();
166+ if (thrownTypes == null || thrownTypes .isEmpty ()) {
167+ thrown = List .nil ();
168+ } else {
169+ for (Type thrownType : thrownTypes ) {
170+ JCTree .JCIdent ident = treeMaker .Ident (thrownType .tsym );
171+ if (thrown == null ) {
172+ thrown = List .of ((JCTree .JCExpression ) ident );
173+ } else {
174+ thrown = thrown .append (ident );
175+ }
176+ }
177+ }
178+
179+ return treeMaker .MethodDef (mod , name , restype , typarams , params , thrown , null , null );
100180 }
101181}
0 commit comments