AsmMethodParam
This commit is contained in:
@@ -12,11 +12,13 @@ import org.redkale.convert.json.JsonConvert;
|
|||||||
/**
|
/**
|
||||||
* 存放方法的字节信息
|
* 存放方法的字节信息
|
||||||
*
|
*
|
||||||
|
* @see org.redkale.asm.AsmMethodBoost
|
||||||
|
*
|
||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
*/
|
*/
|
||||||
public class AsmMethodBean {
|
public class AsmMethodBean {
|
||||||
|
|
||||||
private List<String> fieldNames;
|
private List<AsmMethodParam> params;
|
||||||
|
|
||||||
private int access;
|
private int access;
|
||||||
|
|
||||||
@@ -37,7 +39,7 @@ public class AsmMethodBean {
|
|||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.exceptions = exceptions;
|
this.exceptions = exceptions;
|
||||||
this.fieldNames = new ArrayList<>();
|
this.params = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsmMethodBean get(Map<String, AsmMethodBean> map, Method method) {
|
public static AsmMethodBean get(Map<String, AsmMethodBean> map, Method method) {
|
||||||
@@ -45,21 +47,41 @@ public class AsmMethodBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void removeEmptyNames() {
|
void removeEmptyNames() {
|
||||||
if (fieldNames != null) {
|
if (params != null) {
|
||||||
while (fieldNames.remove(" "));
|
List<AsmMethodParam> dels = null;
|
||||||
|
for (AsmMethodParam p : params) {
|
||||||
|
if (" ".equals(p.getName())) {
|
||||||
|
if (dels == null) {
|
||||||
|
dels = new ArrayList<>();
|
||||||
|
}
|
||||||
|
dels.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dels != null) {
|
||||||
|
for (AsmMethodParam p : dels) {
|
||||||
|
params.remove(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] fieldNameArray() {
|
public String[] fieldNameArray() {
|
||||||
return fieldNames == null ? null : fieldNames.toArray(new String[fieldNames.size()]);
|
if (params == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] rs = new String[params.size()];
|
||||||
|
for (int i = 0; i < rs.length; i++) {
|
||||||
|
rs[i] = params.get(i).getName();
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getFieldNames() {
|
public List<AsmMethodParam> getParams() {
|
||||||
return fieldNames;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFieldNames(List<String> fieldNames) {
|
public void setParams(List<AsmMethodParam> params) {
|
||||||
this.fieldNames = fieldNames;
|
this.params = params;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAccess() {
|
public int getAccess() {
|
||||||
|
|||||||
@@ -223,9 +223,10 @@ public abstract class AsmMethodBoost<T> {
|
|||||||
Label l2 = new Label();
|
Label l2 = new Label();
|
||||||
mv.visitLabel(l2);
|
mv.visitLabel(l2);
|
||||||
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
|
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
|
||||||
List<String> fieldNames = methodBean.getFieldNames();
|
List<AsmMethodParam> params = methodBean.getParams();
|
||||||
for (int i = 0; i < paramTypes.length; i++) {
|
for (int i = 0; i < paramTypes.length; i++) {
|
||||||
mv.visitLocalVariable(fieldNames.get(i), Type.getDescriptor(paramTypes[i]), null, l0, l2, insns.get(i));
|
AsmMethodParam param = params.get(i);
|
||||||
|
mv.visitLocalVariable(param.getName(), param.getDescription(), param.getSignature(), l0, l2, insns.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,11 +303,11 @@ public abstract class AsmMethodBoost<T> {
|
|||||||
|
|
||||||
static class MethodParamClassVisitor extends ClassVisitor {
|
static class MethodParamClassVisitor extends ClassVisitor {
|
||||||
|
|
||||||
private final Map<String, AsmMethodBean> fieldMap;
|
private final Map<String, AsmMethodBean> methodBeanMap;
|
||||||
|
|
||||||
public MethodParamClassVisitor(int api, final Map<String, AsmMethodBean> fieldmap) {
|
public MethodParamClassVisitor(int api, final Map<String, AsmMethodBean> fieldmap) {
|
||||||
super(api);
|
super(api);
|
||||||
this.fieldMap = fieldmap;
|
this.methodBeanMap = fieldmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -315,27 +316,27 @@ public abstract class AsmMethodBoost<T> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String key = name + ":" + desc;
|
String key = name + ":" + desc;
|
||||||
if (fieldMap.containsKey(key)) {
|
if (methodBeanMap.containsKey(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
AsmMethodBean bean = new AsmMethodBean(access, name, desc, signature, exceptions);
|
AsmMethodBean bean = new AsmMethodBean(access, name, desc, signature, exceptions);
|
||||||
List<String> fieldNames = bean.getFieldNames();
|
List<AsmMethodParam> paramList = bean.getParams();
|
||||||
fieldMap.put(key, bean);
|
methodBeanMap.put(key, bean);
|
||||||
return new MethodVisitor(Opcodes.ASM6) {
|
return new MethodVisitor(Opcodes.ASM6) {
|
||||||
@Override
|
@Override
|
||||||
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
|
||||||
if (index < 1) {
|
if (index < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int size = fieldNames.size();
|
int size = paramList.size();
|
||||||
//index并不会按顺序执行的
|
//index并不会按顺序执行
|
||||||
if (index > size) {
|
if (index > size) {
|
||||||
for (int i = size; i < index; i++) {
|
for (int i = size; i < index; i++) {
|
||||||
fieldNames.add(" ");
|
paramList.add(new AsmMethodParam(" ", description, signature));
|
||||||
}
|
}
|
||||||
fieldNames.set(index - 1, name);
|
paramList.set(index - 1, new AsmMethodParam(name, description, signature));
|
||||||
}
|
}
|
||||||
fieldNames.set(index - 1, name);
|
paramList.set(index - 1, new AsmMethodParam(name, description, signature));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/main/java/org/redkale/asm/AsmMethodParam.java
Normal file
61
src/main/java/org/redkale/asm/AsmMethodParam.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.redkale.asm;
|
||||||
|
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放方法参数的字节信息
|
||||||
|
*
|
||||||
|
* @see org.redkale.asm.AsmMethodBean
|
||||||
|
* @see org.redkale.asm.AsmMethodBoost
|
||||||
|
*
|
||||||
|
* @since 2.8.0
|
||||||
|
*/
|
||||||
|
public class AsmMethodParam {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String signature;
|
||||||
|
|
||||||
|
public AsmMethodParam() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmMethodParam(String name, String description, String signature) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSignature() {
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignature(String signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -622,26 +622,26 @@ public final class Rest {
|
|||||||
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
|
ClassWriter cw2 = new ClassWriter(COMPUTE_FRAMES);
|
||||||
cw2.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynSuperMessageFullName, null, "java/lang/Object", new String[]{webSocketParamName, "java/lang/Runnable"});
|
cw2.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynSuperMessageFullName, null, "java/lang/Object", new String[]{webSocketParamName, "java/lang/Runnable"});
|
||||||
cw2.visitInnerClass(newDynSuperMessageFullName, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
|
cw2.visitInnerClass(newDynSuperMessageFullName, newDynName, newDynMessageSimpleName + endfix, ACC_PUBLIC + ACC_STATIC);
|
||||||
Set<String> paramnames = new HashSet<>();
|
Set<String> paramNames = new HashSet<>();
|
||||||
AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method);
|
AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method);
|
||||||
List<String> names = methodBean == null ? null : methodBean.getFieldNames();
|
List<AsmMethodParam> names = methodBean == null ? null : methodBean.getParams();
|
||||||
Parameter[] params = method.getParameters();
|
Parameter[] params = method.getParameters();
|
||||||
final LinkedHashMap<String, Parameter> paramap = new LinkedHashMap(); //必须使用LinkedHashMap确保顺序
|
final LinkedHashMap<String, Parameter> paramap = new LinkedHashMap(); //必须使用LinkedHashMap确保顺序
|
||||||
for (int j = 0; j < params.length; j++) { //字段列表
|
for (int j = 0; j < params.length; j++) { //字段列表
|
||||||
Parameter param = params[j];
|
Parameter param = params[j];
|
||||||
String paramname = param.getName();
|
String paramName = param.getName();
|
||||||
RestParam rp = param.getAnnotation(RestParam.class);
|
RestParam rp = param.getAnnotation(RestParam.class);
|
||||||
if (rp != null && !rp.name().isEmpty()) {
|
if (rp != null && !rp.name().isEmpty()) {
|
||||||
paramname = rp.name();
|
paramName = rp.name();
|
||||||
} else if (names != null && names.size() > j) {
|
} else if (names != null && names.size() > j) {
|
||||||
paramname = names.get(j);
|
paramName = names.get(j).getName();
|
||||||
}
|
}
|
||||||
if (paramnames.contains(paramname)) {
|
if (paramNames.contains(paramName)) {
|
||||||
throw new RestException(method + " has same @RestParam.name");
|
throw new RestException(method + " has same @RestParam.name");
|
||||||
}
|
}
|
||||||
paramnames.add(paramname);
|
paramNames.add(paramName);
|
||||||
paramap.put(paramname, param);
|
paramap.put(paramName, param);
|
||||||
fv = cw2.visitField(ACC_PUBLIC, paramname, Type.getDescriptor(param.getType()),
|
fv = cw2.visitField(ACC_PUBLIC, paramName, Type.getDescriptor(param.getType()),
|
||||||
param.getType() == param.getParameterizedType() ? null : Utility.getTypeDescriptor(param.getParameterizedType()), null);
|
param.getType() == param.getParameterizedType() ? null : Utility.getTypeDescriptor(param.getParameterizedType()), null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
@@ -1890,7 +1890,7 @@ public final class Rest {
|
|||||||
int maxLocals = 4;
|
int maxLocals = 4;
|
||||||
|
|
||||||
AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method);
|
AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method);
|
||||||
List<String> asmParamNames = methodBean == null ? null : methodBean.getFieldNames();
|
List<AsmMethodParam> asmParamNames = methodBean == null ? null : methodBean.getParams();
|
||||||
List<Object[]> paramlist = new ArrayList<>();
|
List<Object[]> paramlist = new ArrayList<>();
|
||||||
//解析方法中的每个参数
|
//解析方法中的每个参数
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
@@ -2180,7 +2180,7 @@ public final class Rest {
|
|||||||
n = "?"; //Http参数类型特殊处理
|
n = "?"; //Http参数类型特殊处理
|
||||||
}
|
}
|
||||||
if (n == null && asmParamNames != null && asmParamNames.size() > i) {
|
if (n == null && asmParamNames != null && asmParamNames.size() > i) {
|
||||||
n = asmParamNames.get(i);
|
n = asmParamNames.get(i).getName();
|
||||||
}
|
}
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
if (param.isNamePresent()) {
|
if (param.isNamePresent()) {
|
||||||
|
|||||||
@@ -637,9 +637,10 @@ public abstract class Sncp {
|
|||||||
Label l2 = new Label();
|
Label l2 = new Label();
|
||||||
mv.visitLabel(l2);
|
mv.visitLabel(l2);
|
||||||
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
|
//mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0);
|
||||||
List<String> fieldNames = methodBean.getFieldNames();
|
List<AsmMethodParam> params = methodBean.getParams();
|
||||||
for (int i = 0; i < paramTypes.length; i++) {
|
for (int i = 0; i < paramTypes.length; i++) {
|
||||||
mv.visitLocalVariable(fieldNames.get(i), Type.getDescriptor(paramTypes[i]), null, l0, l2, insns.get(i));
|
AsmMethodParam param = params.get(i);
|
||||||
|
mv.visitLocalVariable(param.getName(), param.getDescription(), param.getSignature(), l0, l2, insns.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mv.visitMaxs(20, 20);
|
mv.visitMaxs(20, 20);
|
||||||
|
|||||||
Reference in New Issue
Block a user