Skip to content

Commit 775f6ca

Browse files
author
wangshuwen
committed
feat:支持方法调用入参泛型&转换
1 parent 93377e4 commit 775f6ca

File tree

5 files changed

+115
-163
lines changed

5 files changed

+115
-163
lines changed

xrouter_compiler/src/main/java/cn/cheney/xrouter/compiler/contant/XTypeMirror.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package cn.cheney.xrouter.compiler.contant;
22

3+
import com.squareup.javapoet.ClassName;
4+
35
public class XTypeMirror {
46
//java
57
private static final String LANG = "java.lang";
@@ -27,5 +29,10 @@ public class XTypeMirror {
2729
public static final String SYRINGE = "cn.cheney.xrouter.core.syringe.Syringe";
2830
public static final String PARAM_INFO = "cn.cheney.xrouter.core.invok.ParamInfo";
2931

32+
//ClassName
33+
public static final ClassName CLASSNAME_TYPE_REFERENCE = ClassName.get("com.alibaba.fastjson",
34+
"TypeReference");
35+
public static final ClassName CLASSNAME_METHOD_INVOKABLE = ClassName.get("cn.cheney.xrouter.core.invok",
36+
"MethodInvokable");
3037

3138
}

xrouter_compiler/src/main/java/cn/cheney/xrouter/compiler/generator/ModuleClassGenerator.java

Lines changed: 103 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.squareup.javapoet.ParameterizedTypeName;
77
import com.squareup.javapoet.TypeName;
88
import com.squareup.javapoet.TypeSpec;
9-
import com.sun.tools.javac.util.Pair;
109

1110
import java.io.IOException;
1211
import java.util.ArrayList;
@@ -111,7 +110,7 @@ public void generateSeg(TypeElement classType, String path) {
111110
for (Element element : classType.getEnclosedElements()) {
112111
if (element instanceof ExecutableElement) {
113112
ExecutableElement executableElement = (ExecutableElement) element;
114-
addMethodInvoke(holder, classType, executableElement);
113+
addMethodInvoke(classType, executableElement);
115114
}
116115
}
117116
}
@@ -188,12 +187,7 @@ private void addActivityInvoke(TypeElement activityType, String path) {
188187
}
189188

190189

191-
private void addMethodInvoke(XRouterProcessor.Holder holder,
192-
TypeElement classType,
193-
ExecutableElement methodElement) {
194-
TypeMirror paramInfoType = holder.elementUtils
195-
.getTypeElement(XTypeMirror.PARAM_INFO).asType();
196-
190+
private void addMethodInvoke(TypeElement classType, ExecutableElement methodElement) {
197191
XMethod xMethod = methodElement.getAnnotation(XMethod.class);
198192
if (null == xMethod) {
199193
return;
@@ -211,127 +205,53 @@ private void addMethodInvoke(XRouterProcessor.Holder holder,
211205
methodElement.getSimpleName()));
212206
return;
213207
}
208+
214209
TypeMirror returnType = methodElement.getReturnType();
215210
boolean isReturnVoid = TypeKind.VOID.equals(returnType.getKind());
216-
217211
List<? extends VariableElement> parameters = methodElement.getParameters();
218-
219-
//TestModule.testMethod()
220-
List<Object> paramsSegList = new ArrayList<>();
221-
paramsSegList.add(classType);
222-
paramsSegList.add(methodElement.getSimpleName().toString());
223-
224-
StringBuilder paramSeg = new StringBuilder();
225-
if (isReturnVoid) {
226-
paramSeg.append("$T.$L(");
227-
} else {
228-
paramSeg.append("return $T.$L(");
229-
}
230-
231-
StringBuilder paramsInfoSeg = new StringBuilder();
232-
//整体构造MethodInvokable的value
212+
//new MethodInvokable()所有参数的值
233213
List<Object> allInfoSegList = new ArrayList<>();
234-
//构造paramInfo的value
235-
List<Object> paramsInfoSegList = new ArrayList<>();
236-
237-
boolean hasRequestId = false;
238-
boolean hasContext = false;
239-
if (null != parameters && !parameters.isEmpty()) {
240-
for (VariableElement variableElement : parameters) {
241-
boolean isNeedConvert = false;
242-
javax.lang.model.type.TypeMirror methodParamType = variableElement.asType();
243-
//擦除泛型[因为Map<String>.class 不允许]
244-
if (methodParamType instanceof DeclaredType) {
245-
DeclaredType methodParamDeclaredType = (DeclaredType) methodParamType;
246-
if (!methodParamDeclaredType.getTypeArguments().isEmpty()) {
247-
isNeedConvert = true;
248-
Logger.d("泛型 " + methodParamType.toString());
249-
}
250-
}
251-
XParam xParam = variableElement.getAnnotation(XParam.class);
252-
String key = getParamName(xParam, variableElement.getSimpleName().toString());
253-
//如果是context类型 key=XParam.Context
254-
if (variableElement.asType().toString().equals(XTypeMirror.CONTEXT)) {
255-
key = XParam.Context;
256-
}
257-
if (key.equals(XParam.RequestId)) {
258-
if (hasRequestId) {
259-
Logger.e(String.format("[%s] [%s] have repeat key requestId",
260-
classType.getQualifiedName(),
261-
methodElement.getSimpleName()));
262-
return;
263-
}
264-
hasRequestId = true;
265-
}
266-
if (key.equals(XParam.Context)) {
267-
if (hasContext) {
268-
Logger.e(String.format("[%s] [%s] have repeat key context",
269-
classType.getQualifiedName(),
270-
methodElement.getSimpleName()));
271-
return;
272-
}
273-
hasContext = true;
274-
}
275-
if (parameters.indexOf(variableElement) == parameters.size() - 1) {
276-
paramSeg.append("($T)params.get($S)");
277-
paramsInfoSeg.append("new $T($S,$T.class)");
278-
} else {
279-
paramSeg.append("($T)params.get($S),");
280-
paramsInfoSeg.append("new $T($S,$T.class),");
281-
}
282-
paramsSegList.add(methodParamType);
283-
paramsSegList.add(key);
284-
285-
paramsInfoSegList.add(paramInfoType);
286-
paramsInfoSegList.add(getParamName(xParam, variableElement.getSimpleName().toString()));
287-
paramsInfoSegList.add(methodParamType);
288-
289-
}
290-
}
291-
paramSeg.append(")");
292214
//返回类型的泛型className
293215
TypeName returnClassName;
294216
if (!isReturnVoid) {
295217
returnClassName = TypeName.get(returnType);
296218
} else {
297219
returnClassName = ClassName.bestGuess("java.lang.Void");
298220
}
299-
ParameterizedTypeName methodInvokableType =
300-
ParameterizedTypeName.get(ClassName.get("cn.cheney.xrouter.core.invok", "MethodInvokable"), returnClassName);
301-
/*
302-
* new MethodInvokable(RouteType.METHOD,YourClazz.class,module,path) {
303-
* @Override
304-
* public Object invoke(Map<String, Object> params) {
305-
* return YourClass.YourMethod(params.get(yourKey));
306-
* }
307-
* }
308-
*/
221+
MethodParamCodeBean methodParamCodeBean = generateParamCode(classType, methodElement, parameters);
222+
if (null == methodParamCodeBean) {
223+
return;
224+
}
225+
//Override invoke
309226
MethodSpec.Builder invokeBuilder = MethodSpec.methodBuilder("invoke")
310227
.addAnnotation(Override.class)
311228
.addModifiers(Modifier.PUBLIC)
312229
.addParameter(ParameterizedTypeName.get(
313230
ClassName.get(Map.class),
314231
ClassName.get(String.class),
315232
ClassName.get(Object.class)), "params")
316-
.addStatement(paramSeg.toString(), paramsSegList.toArray())
233+
.addStatement(methodParamCodeBean.invokeImplDesc.toString(),
234+
methodParamCodeBean.invokeImplValueList.toArray())
317235
.returns(returnClassName);
318-
319236
if (isReturnVoid) {
320237
invokeBuilder.addStatement("return null");
321238
}
322-
239+
//new MethodInvokable(RouteType.METHOD,YourClazz.class,module,path)
323240
String methodInvokeClassStr = "$T.METHOD,$T.class,$S,$S,$L";
324-
if (!paramsInfoSeg.toString().isEmpty()) {
325-
methodInvokeClassStr += "," + paramsInfoSeg.toString();
326-
}
327241

242+
if (!methodParamCodeBean.paramsInfoDesc.toString().isEmpty()) {
243+
methodInvokeClassStr += "," + methodParamCodeBean.paramsInfoDesc.toString();
244+
}
245+
Logger.d(" " + methodInvokeClassStr);
328246
allInfoSegList.add(RouteType.class);
329247
allInfoSegList.add(classType);
330248
allInfoSegList.add(module);
331249
allInfoSegList.add(xMethod.name());
332-
allInfoSegList.add(hasRequestId);
333-
allInfoSegList.addAll(paramsInfoSegList);
334-
250+
allInfoSegList.add(methodParamCodeBean.isASync);
251+
allInfoSegList.addAll(methodParamCodeBean.paramsInfoValueList);
252+
//MethodInvokable<R>的类型
253+
ParameterizedTypeName methodInvokableType = ParameterizedTypeName.get(XTypeMirror.CLASSNAME_METHOD_INVOKABLE
254+
, returnClassName);
335255
TypeSpec methodInvoke = TypeSpec.anonymousClassBuilder(methodInvokeClassStr, allInfoSegList.toArray())
336256
.addSuperinterface(methodInvokableType)
337257
.addMethod(invokeBuilder.build())
@@ -340,73 +260,98 @@ private void addMethodInvoke(XRouterProcessor.Holder holder,
340260
}
341261

342262

343-
private Pair<Pair<String, List<Object>>,
344-
Pair<String, List<Object>>> newParamInfo(String className,
345-
String methodName,
346-
List<? extends VariableElement> parameters) {
263+
/**
264+
* @param classType 类
265+
* @param methodElement 方法
266+
* @param parameters 方法参数
267+
* @return new ParamInfo("key1", Clazz),new ParamInfo("key2", Clazz)...
268+
* YourClass.YourMethod(params.get ( yourKey))
269+
*/
270+
private MethodParamCodeBean generateParamCode(TypeElement classType,
271+
ExecutableElement methodElement,
272+
List<? extends VariableElement> parameters) {
273+
boolean isReturnVoid = TypeKind.VOID.equals(methodElement.getReturnType().getKind());
347274
TypeMirror paramInfoType = holder.elementUtils
348275
.getTypeElement(XTypeMirror.PARAM_INFO).asType();
349-
//new ParamInfo()描述
350-
StringBuilder paramsInfoDesc = new StringBuilder();
351-
//new ParamInfo() value
352-
List<Object> paramsInfoValueList = new ArrayList<>();
353276

354-
boolean hasRequestId = false;
355-
boolean hasContext = false;
356-
if (null == parameters || parameters.isEmpty()) {
357-
// return Pair.of(paramsInfoDesc.toString(), paramsInfoValueList);
277+
MethodParamCodeBean paramCodeBean = new MethodParamCodeBean();
278+
paramCodeBean.invokeImplValueList.add(classType);
279+
paramCodeBean.invokeImplValueList.add(methodElement.getSimpleName().toString());
280+
281+
if (isReturnVoid) {
282+
paramCodeBean.invokeImplDesc.append("$T.$L(");
283+
} else {
284+
paramCodeBean.invokeImplDesc.append("return $T.$L(");
358285
}
359-
for (VariableElement variableElement : parameters) {
360-
boolean isNeedConvert = false;
361-
javax.lang.model.type.TypeMirror methodParamType = variableElement.asType();
362-
//擦除泛型[因为Map<String>.class 不允许]
363-
if (methodParamType instanceof DeclaredType) {
364-
DeclaredType methodParamDeclaredType = (DeclaredType) methodParamType;
365-
if (!methodParamDeclaredType.getTypeArguments().isEmpty()) {
366-
isNeedConvert = true;
367-
Logger.d("泛型 " + methodParamType.toString());
286+
List<String> alreadyExistList = new ArrayList<>();
287+
if (null != parameters && !parameters.isEmpty()) {
288+
for (VariableElement variableElement : parameters) {
289+
boolean isGenerics = false;
290+
javax.lang.model.type.TypeMirror paramType = variableElement.asType();
291+
if (paramType instanceof DeclaredType) {
292+
DeclaredType methodParamDeclaredType = (DeclaredType) paramType;
293+
if (!methodParamDeclaredType.getTypeArguments().isEmpty()) {
294+
isGenerics = true;
295+
Logger.d("泛型 " + paramType.toString());
296+
}
368297
}
369-
}
370-
XParam xParam = variableElement.getAnnotation(XParam.class);
371-
String key = getParamName(xParam, variableElement.getSimpleName().toString());
372-
//如果是context类型 key=XParam.Context
373-
if (variableElement.asType().toString().equals(XTypeMirror.CONTEXT)) {
374-
key = XParam.Context;
375-
}
376-
if (key.equals(XParam.RequestId)) {
377-
if (hasRequestId) {
378-
Logger.e(String.format("[%s] [%s] have repeat key requestId", className,
379-
methodName));
298+
XParam xParam = variableElement.getAnnotation(XParam.class);
299+
String key = getParamName(xParam, variableElement.getSimpleName().toString());
300+
if (alreadyExistList.contains(key)) {
301+
Logger.e(String.format("[%s] [%s] have repeat key %s", classType.getSimpleName().toString(),
302+
methodElement.getSimpleName().toString(), key));
380303
return null;
381304
}
382-
hasRequestId = true;
383-
}
384-
if (key.equals(XParam.Context)) {
385-
if (hasContext) {
386-
// Logger.e(String.format("[%s] [%s] have repeat key context",
387-
// classType.getQualifiedName(),
388-
// methodElement.getSimpleName()));
389-
Logger.e(String.format("[%s] [%s] have repeat key context", className,
390-
methodName));
391-
return null;
305+
if (variableElement.asType().toString().equals(XTypeMirror.CONTEXT)) {
306+
key = XParam.Context;
392307
}
393-
hasContext = true;
394-
}
395-
if (parameters.indexOf(variableElement) == parameters.size() - 1) {
396-
//paramSeg.append("($T)params.get($S)");
397-
paramsInfoDesc.append("new $T($S,$T.class)");
398-
} else {
399-
//paramSeg.append("($T)params.get($S),");
400-
paramsInfoDesc.append("new $T($S,$T.class),");
308+
alreadyExistList.add(key);
309+
if (parameters.indexOf(variableElement) == parameters.size() - 1) {
310+
if (isGenerics) {
311+
paramCodeBean.paramsInfoDesc.append("new $T($S,new $T(){}.getType())");
312+
} else {
313+
paramCodeBean.paramsInfoDesc.append("new $T($S,$T.class)");
314+
}
315+
paramCodeBean.invokeImplDesc.append("($T)params.get($S)");
316+
} else {
317+
if (isGenerics) {
318+
paramCodeBean.paramsInfoDesc.append("new $T($S,new $T(){}.getType()),");
319+
} else {
320+
paramCodeBean.paramsInfoDesc.append("new $T($S,$T.class),");
321+
}
322+
paramCodeBean.invokeImplDesc.append("($T)params.get($S),");
323+
}
324+
325+
paramCodeBean.paramsInfoValueList.add(paramInfoType);
326+
paramCodeBean.paramsInfoValueList.add(getParamName(xParam,
327+
variableElement.getSimpleName().toString()));
328+
if (isGenerics) {
329+
ParameterizedTypeName methodInvokableType = ParameterizedTypeName.get(
330+
XTypeMirror.CLASSNAME_TYPE_REFERENCE, TypeName.get(paramType));
331+
paramCodeBean.paramsInfoValueList.add(methodInvokableType);
332+
} else {
333+
paramCodeBean.paramsInfoValueList.add(paramType);
334+
}
335+
336+
paramCodeBean.invokeImplValueList.add(paramType);
337+
paramCodeBean.invokeImplValueList.add(key);
401338
}
402-
// paramsSegList.add(methodParamType);
403-
// paramsSegList.add(key);
404-
paramsInfoValueList.add(paramInfoType);
405-
paramsInfoValueList.add(getParamName(xParam, variableElement.getSimpleName().toString()));
406-
paramsInfoValueList.add(methodParamType);
407339
}
408-
// return Pair.of(paramsInfoDesc.toString(), paramsInfoValueList);
409-
return null;
340+
paramCodeBean.invokeImplDesc.append(")");
341+
paramCodeBean.isASync = alreadyExistList.contains(XParam.RequestId);
342+
return paramCodeBean;
343+
}
344+
345+
346+
static class MethodParamCodeBean {
347+
//new ParamInfo("key1", Clazz),new ParamInfo("key2", Clazz)...
348+
StringBuilder paramsInfoDesc = new StringBuilder();
349+
List<Object> paramsInfoValueList = new ArrayList<>();
350+
//YourClass.YourMethod(params.get (yourKey))
351+
StringBuilder invokeImplDesc = new StringBuilder();
352+
List<Object> invokeImplValueList = new ArrayList<>();
353+
boolean isASync;
410354
}
411355

356+
412357
}

xrouter_core/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ android {
2626

2727
dependencies {
2828
implementation fileTree(dir: 'libs', include: ['*.jar'])
29-
implementation 'com.alibaba:fastjson:1.2.23'
29+
api 'com.alibaba:fastjson:1.2.23'
3030
api project(":xrouter_annotation")
3131
// api 'cn.cheney.xrouter:annotation:1.0.2'
3232
}

xrouter_core/src/main/java/cn/cheney/xrouter/core/invok/ParamInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package cn.cheney.xrouter.core.invok;
22

3+
import com.alibaba.fastjson.TypeReference;
4+
35
import java.lang.reflect.Type;
6+
import java.util.Map;
47

58
public class ParamInfo {
69

@@ -10,6 +13,7 @@ public class ParamInfo {
1013
public ParamInfo(String name, Type type) {
1114
this.name = name;
1215
this.type = type;
16+
this.type = new TypeReference<Map<String, Object>>(){}.getType();
1317
}
1418

1519
public String getName() {

xrouter_core/src/main/java/cn/cheney/xrouter/core/method/IMethod.java

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)