AsmMethodParam

This commit is contained in:
redkale
2023-12-21 15:30:21 +08:00
parent 382ad87c5f
commit 95b08e1db0
5 changed files with 120 additions and 35 deletions

View File

@@ -12,11 +12,13 @@ import org.redkale.convert.json.JsonConvert;
/**
* 存放方法的字节信息
*
* @see org.redkale.asm.AsmMethodBoost
*
* @since 2.8.0
*/
public class AsmMethodBean {
private List<String> fieldNames;
private List<AsmMethodParam> params;
private int access;
@@ -37,7 +39,7 @@ public class AsmMethodBean {
this.desc = desc;
this.signature = signature;
this.exceptions = exceptions;
this.fieldNames = new ArrayList<>();
this.params = new ArrayList<>();
}
public static AsmMethodBean get(Map<String, AsmMethodBean> map, Method method) {
@@ -45,21 +47,41 @@ public class AsmMethodBean {
}
void removeEmptyNames() {
if (fieldNames != null) {
while (fieldNames.remove(" "));
if (params != null) {
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() {
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() {
return fieldNames;
public List<AsmMethodParam> getParams() {
return params;
}
public void setFieldNames(List<String> fieldNames) {
this.fieldNames = fieldNames;
public void setParams(List<AsmMethodParam> params) {
this.params = params;
}
public int getAccess() {

View File

@@ -223,9 +223,10 @@ public abstract class AsmMethodBoost<T> {
Label l2 = new Label();
mv.visitLabel(l2);
//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++) {
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 {
private final Map<String, AsmMethodBean> fieldMap;
private final Map<String, AsmMethodBean> methodBeanMap;
public MethodParamClassVisitor(int api, final Map<String, AsmMethodBean> fieldmap) {
super(api);
this.fieldMap = fieldmap;
this.methodBeanMap = fieldmap;
}
@Override
@@ -315,27 +316,27 @@ public abstract class AsmMethodBoost<T> {
return null;
}
String key = name + ":" + desc;
if (fieldMap.containsKey(key)) {
if (methodBeanMap.containsKey(key)) {
return null;
}
AsmMethodBean bean = new AsmMethodBean(access, name, desc, signature, exceptions);
List<String> fieldNames = bean.getFieldNames();
fieldMap.put(key, bean);
List<AsmMethodParam> paramList = bean.getParams();
methodBeanMap.put(key, bean);
return new MethodVisitor(Opcodes.ASM6) {
@Override
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
if (index < 1) {
return;
}
int size = fieldNames.size();
//index并不会按顺序执行
int size = paramList.size();
//index并不会按顺序执行
if (index > size) {
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));
}
};
}

View 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);
}
}

View File

@@ -622,26 +622,26 @@ public final class Rest {
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.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);
List<String> names = methodBean == null ? null : methodBean.getFieldNames();
List<AsmMethodParam> names = methodBean == null ? null : methodBean.getParams();
Parameter[] params = method.getParameters();
final LinkedHashMap<String, Parameter> paramap = new LinkedHashMap(); //必须使用LinkedHashMap确保顺序
for (int j = 0; j < params.length; j++) { //字段列表
Parameter param = params[j];
String paramname = param.getName();
String paramName = param.getName();
RestParam rp = param.getAnnotation(RestParam.class);
if (rp != null && !rp.name().isEmpty()) {
paramname = rp.name();
paramName = rp.name();
} 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");
}
paramnames.add(paramname);
paramap.put(paramname, param);
fv = cw2.visitField(ACC_PUBLIC, paramname, Type.getDescriptor(param.getType()),
paramNames.add(paramName);
paramap.put(paramName, param);
fv = cw2.visitField(ACC_PUBLIC, paramName, Type.getDescriptor(param.getType()),
param.getType() == param.getParameterizedType() ? null : Utility.getTypeDescriptor(param.getParameterizedType()), null);
fv.visitEnd();
}
@@ -1888,9 +1888,9 @@ public final class Rest {
final int maxStack = 3 + params.length;
List<int[]> varInsns = new ArrayList<>();
int maxLocals = 4;
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<>();
//解析方法中的每个参数
for (int i = 0; i < params.length; i++) {
@@ -2180,7 +2180,7 @@ public final class Rest {
n = "?"; //Http参数类型特殊处理
}
if (n == null && asmParamNames != null && asmParamNames.size() > i) {
n = asmParamNames.get(i);
n = asmParamNames.get(i).getName();
}
if (n == null) {
if (param.isNamePresent()) {

View File

@@ -637,9 +637,10 @@ public abstract class Sncp {
Label l2 = new Label();
mv.visitLabel(l2);
//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++) {
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);