From 95b08e1db002b63fbbfbca0ae144619bcae39953 Mon Sep 17 00:00:00 2001 From: redkale Date: Thu, 21 Dec 2023 15:30:21 +0800 Subject: [PATCH] AsmMethodParam --- .../java/org/redkale/asm/AsmMethodBean.java | 40 +++++++++--- .../java/org/redkale/asm/AsmMethodBoost.java | 25 ++++---- .../java/org/redkale/asm/AsmMethodParam.java | 61 +++++++++++++++++++ src/main/java/org/redkale/net/http/Rest.java | 24 ++++---- src/main/java/org/redkale/net/sncp/Sncp.java | 5 +- 5 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 src/main/java/org/redkale/asm/AsmMethodParam.java diff --git a/src/main/java/org/redkale/asm/AsmMethodBean.java b/src/main/java/org/redkale/asm/AsmMethodBean.java index 2d228b077..018ad5dd9 100644 --- a/src/main/java/org/redkale/asm/AsmMethodBean.java +++ b/src/main/java/org/redkale/asm/AsmMethodBean.java @@ -12,11 +12,13 @@ import org.redkale.convert.json.JsonConvert; /** * 存放方法的字节信息 * + * @see org.redkale.asm.AsmMethodBoost + * * @since 2.8.0 */ public class AsmMethodBean { - private List fieldNames; + private List 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 map, Method method) { @@ -45,21 +47,41 @@ public class AsmMethodBean { } void removeEmptyNames() { - if (fieldNames != null) { - while (fieldNames.remove(" ")); + if (params != null) { + List 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 getFieldNames() { - return fieldNames; + public List getParams() { + return params; } - public void setFieldNames(List fieldNames) { - this.fieldNames = fieldNames; + public void setParams(List params) { + this.params = params; } public int getAccess() { diff --git a/src/main/java/org/redkale/asm/AsmMethodBoost.java b/src/main/java/org/redkale/asm/AsmMethodBoost.java index 7dccb2cad..3d210690f 100644 --- a/src/main/java/org/redkale/asm/AsmMethodBoost.java +++ b/src/main/java/org/redkale/asm/AsmMethodBoost.java @@ -223,9 +223,10 @@ public abstract class AsmMethodBoost { Label l2 = new Label(); mv.visitLabel(l2); //mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0); - List fieldNames = methodBean.getFieldNames(); + List 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 { static class MethodParamClassVisitor extends ClassVisitor { - private final Map fieldMap; + private final Map methodBeanMap; public MethodParamClassVisitor(int api, final Map fieldmap) { super(api); - this.fieldMap = fieldmap; + this.methodBeanMap = fieldmap; } @Override @@ -315,27 +316,27 @@ public abstract class AsmMethodBoost { 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 fieldNames = bean.getFieldNames(); - fieldMap.put(key, bean); + List 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)); } }; } diff --git a/src/main/java/org/redkale/asm/AsmMethodParam.java b/src/main/java/org/redkale/asm/AsmMethodParam.java new file mode 100644 index 000000000..e697bf58c --- /dev/null +++ b/src/main/java/org/redkale/asm/AsmMethodParam.java @@ -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); + } +} diff --git a/src/main/java/org/redkale/net/http/Rest.java b/src/main/java/org/redkale/net/http/Rest.java index ae3bc8871..88ecd47f0 100644 --- a/src/main/java/org/redkale/net/http/Rest.java +++ b/src/main/java/org/redkale/net/http/Rest.java @@ -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 paramnames = new HashSet<>(); + Set paramNames = new HashSet<>(); AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method); - List names = methodBean == null ? null : methodBean.getFieldNames(); + List names = methodBean == null ? null : methodBean.getParams(); Parameter[] params = method.getParameters(); final LinkedHashMap 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 varInsns = new ArrayList<>(); int maxLocals = 4; - + AsmMethodBean methodBean = asmParamMap == null ? null : AsmMethodBean.get(asmParamMap, method); - List asmParamNames = methodBean == null ? null : methodBean.getFieldNames(); + List asmParamNames = methodBean == null ? null : methodBean.getParams(); List 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()) { diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java index 333e36f1d..68abdfd3a 100644 --- a/src/main/java/org/redkale/net/sncp/Sncp.java +++ b/src/main/java/org/redkale/net/sncp/Sncp.java @@ -637,9 +637,10 @@ public abstract class Sncp { Label l2 = new Label(); mv.visitLabel(l2); //mv.visitLocalVariable("this", thisClassDesc, null, l0, l2, 0); - List fieldNames = methodBean.getFieldNames(); + List 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);