| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.dubbo.erlang.analysis.utils; |
| |
| import org.objectweb.asm.*; |
| |
| |
| import java.io.IOException; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| |
| public class MethodParseUtil { |
| public static String[] getMethodParamNames(final Method method) throws IOException { |
| |
| final String methodName = method.getName(); |
| final Class<?>[] methodParameterTypes = method.getParameterTypes(); |
| final int methodParameterCount = methodParameterTypes.length; |
| final String className = method.getDeclaringClass().getName(); |
| final boolean isStatic = Modifier.isStatic(method.getModifiers()); |
| final String[] methodParametersNames = new String[methodParameterCount]; |
| |
| ClassReader cr = new ClassReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(className.replace('.', '/') + ".class")); |
| ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); |
| cr.accept(new ClassVisitor(Opcodes.ASM5, cw) { |
| public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { |
| |
| MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); |
| |
| final Type[] argTypes = Type.getArgumentTypes(desc); |
| |
| //参数类型不一致 |
| if (!methodName.equals(name) || !matchTypes(argTypes, methodParameterTypes)) { |
| return mv; |
| } |
| |
| return new MethodVisitor(Opcodes.ASM5, mv) { |
| public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { |
| //如果是静态方法,第一个参数就是方法参数,非静态方法,则第一个参数是 this ,然后才是方法的参数 |
| int methodParameterIndex = isStatic ? index : index - 1; |
| if (0 <= methodParameterIndex && methodParameterIndex < methodParameterCount) { |
| methodParametersNames[methodParameterIndex] = name; |
| } |
| super.visitLocalVariable(name, desc, signature, start, end, index); |
| } |
| }; |
| } |
| }, 0); |
| return methodParametersNames; |
| } |
| |
| private static boolean matchTypes(Type[] types, Class<?>[] parameterTypes) { |
| if (types.length != parameterTypes.length) { |
| return false; |
| } |
| for (int i = 0; i < types.length; i++) { |
| if (!Type.getType(parameterTypes[i]).equals(types[i])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |