下面列出了java.lang.annotation.Inherited#org.objectweb.asm.Type 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static boolean validate(String token) {
// Void check
if(token.equals("V"))
return true;
// Ensure type is not an array
Type type = Type.getType(token);
while(type.getSort() == Type.ARRAY)
type = type.getElementType();
// Check for primitives
if(type.getSort() < Type.ARRAY)
return true;
// Verify L...; pattern
// - getDescriptor doesn't modify the original element type (vs getInternalName)
String desc = type.getDescriptor();
return desc.startsWith("L") && desc.endsWith(";");
}
private void visitAnnotationArrayElement(final Expression expr, final int arrayElementType, final AnnotationVisitor av) {
switch (arrayElementType) {
case 1:
AnnotationNode atAttr = (AnnotationNode) ((AnnotationConstantExpression) expr).getValue();
AnnotationVisitor av2 = av.visitAnnotation(null, BytecodeHelper.getTypeDescription(atAttr.getClassNode()));
visitAnnotationAttributes(atAttr, av2);
av2.visitEnd();
break;
case 2:
av.visit(null, ((ConstantExpression) expr).getValue());
break;
case 3:
av.visit(null, Type.getType(BytecodeHelper.getTypeDescription(expr.getType())));
break;
case 4:
PropertyExpression propExpr = (PropertyExpression) expr;
av.visitEnum(null,
BytecodeHelper.getTypeDescription(propExpr.getObjectExpression().getType()),
String.valueOf(((ConstantExpression) propExpr.getProperty()).getValue()));
break;
}
}
@Override
public void generate(CodeEmitter code) {
Label done = new Label();
Label next = new Label();
MethodVisitor mv = code.getMethodVisitor();
BytecodeExpression tgt = code.evaluateOnce(target);
code.exec(tgt);
code.emitInstanceCheck(tgt.getType(), Iterable.class, done);
AssignableValue item = this.item == null ? code.allocate(valueType) : this.item;
AssignableValue iterator = code.allocate(Iterator.class);
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Iterable.class), "iterator", Type.getMethodDescriptor(Type.getType(Iterator.class)), true);
code.exec(iterator.write(code.adapt(Iterator.class)));
mv.visitLabel(next);
code.exec(iterator.read());
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Iterator.class), "hasNext", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), true);
mv.visitJumpInsn(Opcodes.IFEQ, done);
code.exec(iterator.read());
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Iterator.class), "next", Type.getMethodDescriptor(Type.getType(Object.class)), true);
code.cast(valueType, AnyTypeWidget.getInstance()); // , next); // don't skip nulls
code.exec(item.write(item.getType()));
loop.item(code, item.read(), done, next);
mv.visitJumpInsn(Opcodes.GOTO, next);
mv.visitLabel(done);
}
/**
* This is where minecraft checks if you can steer llamas
* @param methodNode
* @param env
*/
@MethodPatch(
mcpName = "canBeSteered",
notchName = "cV",
mcpDesc = "()Z")
public void canBeSteered(MethodNode methodNode, PatchManager.Environment env) {
//create a list of instructions and add the needed instructions to call our hook function
final InsnList insnList = new InsnList();
//call our hook function
insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "canBeSteeredHook", "()Z", false));
//add a label to jump to
final LabelNode jmp = new LabelNode();
//add if equals and pass the label
insnList.add(new JumpInsnNode(IFEQ, jmp));
//add 1 or true
insnList.add(new InsnNode(ICONST_1));
//add return so the rest of the function doesn't get called
insnList.add(new InsnNode(IRETURN));
//add our label
insnList.add(jmp);
//insert the list of instructions at the top of the function
methodNode.instructions.insert(insnList);
}
@Override
public DescAST visit(int lineNo, String line) throws ASTParseException {
try {
String trim = line.trim();
// Verify
if(trim.contains("(")) {
Type type = Type.getMethodType(trim);
if(!validate(type.getReturnType().getDescriptor()))
throw new ASTParseException(lineNo,
"Invalid method return type " + type.getReturnType().getDescriptor());
for(Type arg : type.getArgumentTypes())
if(!validate(arg.getDescriptor()))
throw new ASTParseException(lineNo,
"Invalid method arg type " + arg.getDescriptor());
} else {
if(!validate(trim))
throw new ASTParseException(lineNo, "Invalid field descriptor: " + trim);
}
// Create AST
int start = line.indexOf(trim);
return new DescAST(lineNo, getOffset() + start, trim);
} catch(Exception ex) {
throw new ASTParseException(ex, lineNo, "Bad format for descriptor: " + ex.getMessage());
}
}
@SuppressWarnings("unused")
protected void onMethodEnter() {
if (done) return;
overridden = true;
Label start = new Label();
Label normal = new Label();
super.visitLabel(start);
super.visitFieldInsn(Opcodes.GETSTATIC, CONFIGURATION, CONFIGURATION_FIELD_NAME, Type.INT_TYPE.getDescriptor());
super.visitInsn(Opcodes.DUP);
super.visitJumpInsn(Opcodes.IFEQ, normal);
super.visitInsn(Opcodes.IRETURN);
super.visitLabel(normal);
super.visitInsn(Opcodes.POP);
Label end = new Label();
super.visitJumpInsn(Opcodes.GOTO, end);
super.visitLabel(end);
super.visitTryCatchBlock(start, normal, end, Type.getType(Throwable.class).getDescriptor());
}
@Override
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
if (FingerprintUtil.isSynthetic(access) || Modifier.isPrivate(access))
return;
this.className = Type.getObjectType(name).getClassName();
if (interfaces != null && interfaces.length != 0) {
for (int i = 0; i < interfaces.length; ++i)
interfaces[i] = interfaces[i].replace('/', '.');
this.interfaces = new ArrayList<>();
for (int i = 0; i < interfaces.length; ++i)
this.interfaces.add(interfaces[i]);
}
this.superClass = superName == null || "java/lang/Object".equals(superName) ? null : Type.getObjectType(superName).getClassName();
}
private void pushDefault(Type type) {
switch (type.getSort()) {
case Type.VOID:
break;
case Type.DOUBLE:
mv.visitInsn(DCONST_0);
break;
case Type.LONG:
mv.visitInsn(LCONST_0);
break;
case Type.FLOAT:
mv.visitInsn(FCONST_0);
break;
case Type.OBJECT:
case Type.ARRAY:
mv.visitInsn(ACONST_NULL);
break;
default:
mv.visitInsn(ICONST_0);
break;
}
}
@Override
public void invokeSpecial(final Class<?> clazz, final List<BytecodeExpression> arguments) {
final Type[] args = new Type[arguments.size()];
for (int i = 0; i < arguments.size(); ++i) {
args[i] = arguments.get(i).getType().getJVMType();
}
unit.setSuperInit(
new BytecodeSequence() {
@Override
public void generate(CodeEmitter code) {
code.exec(code.getLocal("this"));
for (BytecodeExpression e : arguments) {
code.exec(e);
}
MethodVisitor mv = code.getMethodVisitor();
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(clazz), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, args), false);
}
}
);
}
/**
* Emits a bridge method for an instance method in a class. For example,
*
* <pre><code>
* class Foo {
* private X execute(A a) {...}
*
* // Synthetic bridge method for a static method.
* static X execute$bridge(Foo foo, A a) {
* return foo.execute(a);
* }
* }
* </code></pre>
*/
@Override
public MethodVisitor visitClassInstanceMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
MethodDeclInfo bridgeMethod = methodDeclInfo.bridgeOfClassInstanceMethod();
MethodVisitor mv = bridgeMethod.accept(cv);
mv.visitCode();
int slotOffset = 0;
for (Type argType : bridgeMethod.argumentTypes()) {
mv.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), slotOffset);
slotOffset += argType.getSize();
}
mv.visitMethodInsn(
Opcodes.INVOKESPECIAL,
methodDeclInfo.ownerName(),
methodDeclInfo.name(),
methodDeclInfo.descriptor(),
/* isInterface= */ false);
mv.visitInsn(bridgeMethod.returnType().getOpcode(Opcodes.IRETURN));
mv.visitMaxs(slotOffset, slotOffset);
mv.visitEnd();
return mv;
}
@Override
public void toCode(MethodVisitor visitor, BytecodeFrontend assembler) {
if (needsSort()) {
sort();
}
int[] cases = new int[targets.size()];
Label[] labels = new Label[targets.size()];
int j = 0;
for (Entry<Integer, BasicBlock> e : targets.entrySet()) {
cases[j] = e.getKey();
labels[j++] = assembler.getLabel(e.getValue());
}
expression.toCode(visitor, assembler);
int[] cast = TypeUtils.getPrimitiveCastOpcodes(expression.getType(), Type.INT_TYPE); // widen
for (int i = 0; i < cast.length; i++) {
visitor.visitInsn(cast[i]);
}
boolean fitsIntoTable = fitsIntoTableSwitch();
if (fitsIntoTable) {
visitor.visitTableSwitchInsn(cases[0], cases[cases.length - 1], assembler.getLabel(defaultTarget), labels);
} else {
visitor.visitLookupSwitchInsn(assembler.getLabel(defaultTarget), cases, labels);
}
}
@Test
@SuppressWarnings("unchecked")
public void testReceiverTypeTypeAnnotationsClassFileRetention() throws Exception {
when(methodDescription.getParameters()).thenReturn((ParameterList) new ParameterList.Empty<ParameterDescription>());
when(methodDescription.getReturnType()).thenReturn(TypeDescription.Generic.VOID);
when(methodDescription.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(methodDescription.getExceptionTypes()).thenReturn(new TypeList.Generic.Empty());
when(methodDescription.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
when(methodDescription.getReceiverType()).thenReturn(simpleAnnotatedType);
when(simpleAnnotatedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance()));
MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER.apply(methodVisitor, methodDescription, annotationValueFilter);
verify(methodVisitor).visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.METHOD_RECEIVER).getValue(),
null,
Type.getDescriptor(AbstractAttributeAppenderTest.QuxBaz.class),
false);
verifyNoMoreInteractions(methodVisitor);
verify(methodDescription).getDeclaredAnnotations();
verify(methodDescription).getParameters();
verify(methodDescription).getReturnType();
verify(methodDescription).getExceptionTypes();
verify(methodDescription).getTypeVariables();
verify(methodDescription).getReceiverType();
verifyNoMoreInteractions(methodDescription);
}
@Test
public void test() {
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "HelloGen", null, "java/lang/Object", null);
FieldVisitor fv = cw.visitField(1, "_key", Type.getDescriptor(String.class), null, null);
fv.visitEnd();
fv = cw.visitField(1, "_value", Type.getDescriptor(InnerClass.class), null, null);
fv.visitEnd();
Class<?> clazz = new DynamicClassLoader().defineClass("HelloGen", cw.toByteArray());
for(Field f : clazz.getDeclaredFields()) {
System.out.println(f.getName());
}
}
private Set<String> getClassDependencies(ClassRelevancyFilter filter, ClassReader reader) {
Set<String> out = new HashSet<String>();
char[] charBuffer = new char[reader.getMaxStringLength()];
for (int i = 1; i < reader.getItemCount(); i++) {
int itemOffset = reader.getItem(i);
if (itemOffset > 0 && reader.readByte(itemOffset - 1) == 7) {
// A CONSTANT_Class entry, read the class descriptor
String classDescriptor = reader.readUTF8(itemOffset, charBuffer);
Type type = Type.getObjectType(classDescriptor);
while (type.getSort() == Type.ARRAY) {
type = type.getElementType();
}
if (type.getSort() != Type.OBJECT) {
// A primitive type
continue;
}
String name = type.getClassName();
if (filter.isRelevant(name)) {
out.add(name);
}
}
}
return out;
}
@Override
public SourceValue unaryOperation(final AbstractInsnNode insn, final SourceValue value) {
int size;
switch (insn.getOpcode()) {
case LNEG:
case DNEG:
case I2L:
case I2D:
case L2D:
case F2L:
case F2D:
case D2L:
size = 2;
break;
case GETFIELD:
size = Type.getType(((FieldInsnNode) insn).desc).getSize();
break;
default:
size = 1;
break;
}
return new SourceValue(size, insn);
}
@Test
@SuppressWarnings("unchecked")
public void testMethodParameterTypeTypeAnnotationClassFileRetention() throws Exception {
when(annotationValueFilter.isRelevant(any(AnnotationDescription.class), any(MethodDescription.InDefinedShape.class))).thenReturn(true);
when(methodDescription.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
ParameterDescription parameterDescription = mock(ParameterDescription.class);
when(parameterDescription.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
when(parameterDescription.getType()).thenReturn(simpleAnnotatedType);
when(methodDescription.getParameters()).thenReturn((ParameterList) new ParameterList.Explicit<ParameterDescription>(parameterDescription));
when(methodDescription.getReturnType()).thenReturn(TypeDescription.Generic.VOID);
when(methodDescription.getTypeVariables()).thenReturn(new TypeList.Generic.Empty());
when(methodDescription.getExceptionTypes()).thenReturn(new TypeList.Generic.Empty());
when(simpleAnnotatedType.getDeclaredAnnotations()).thenReturn(new AnnotationList.ForLoadedAnnotations(new QuxBaz.Instance()));
methodAttributeAppender.apply(methodVisitor, methodDescription, annotationValueFilter);
verify(methodVisitor).visitTypeAnnotation(TypeReference.newFormalParameterReference(0).getValue(),
null,
Type.getDescriptor(QuxBaz.class),
false);
verifyNoMoreInteractions(methodVisitor);
}
private void visitSwap(MethodVisitor mv, Type topType) {
if (topType.getSize() == 1) {
mv.visitInsn(SWAP);
} else {
mv.visitInsn(DUP2_X1);
mv.visitInsn(POP2);
}
}
private static byte[] generateClass(String internalClassName, Type testClassType, int iThread, List<Actor> actors,
List<Object> objArgs, boolean waitsEnabled)
{
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
CheckClassAdapter cca = new CheckClassAdapter(cw, false);
cca.visit(52, ACC_PUBLIC + ACC_SUPER, internalClassName, null, TEST_THREAD_EXECUTION_TYPE.getInternalName(), null);
generateConstructor(cca);
generateRun(cca, testClassType, iThread, actors, objArgs, waitsEnabled);
cca.visitEnd();
return cw.toByteArray();
}
public void declare_field(int access, String name, Type type, Object value) {
FieldInfo existing = (FieldInfo)fieldInfo.get(name);
FieldInfo info = new FieldInfo(access, name, type, value);
if (existing != null) {
if (!info.equals(existing)) {
throw new IllegalArgumentException("Field \"" + name + "\" has been declared differently");
}
} else {
fieldInfo.put(name, info);
cv.visitField(access, name, type.getDescriptor(), null, value);
}
}
/**
* Adds the chain info.
*
* @return the insn list
*/
private InsnList addChainInfo() {
InsnList list = new InsnList();
list.add(new VarInsnNode(Opcodes.ALOAD, 1));
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
CLASSNAME_MAPREDUCEEXECUTIL, "addChainInfo", Type
.getMethodDescriptor(Type.VOID_TYPE, TYPE_JOBCONF)));
return list;
}
/**
* @deprecated use {@link #append_string(CodeEmitter, Type, ArrayDelimiters, CustomizerRegistry)} instead
*/
@Deprecated
public static void append_string(final CodeEmitter e,
Type type,
final ArrayDelimiters delims,
final Customizer customizer) {
append_string(e, type, delims, CustomizerRegistry.singleton(customizer));
}
void addConstant(final Object constant) {
if (constant instanceof Type) {
addType((Type) constant);
} else if (constant instanceof Handle) {
Handle handle = (Handle) constant;
addInternalType(handle.getOwner());
addMethodTypes(handle.getDesc());
}
}
@Override
public void visit(final String name, final Object value) {
checkVisitEndNotCalled();
checkName(name);
if (!(value instanceof Byte
|| value instanceof Boolean
|| value instanceof Character
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long
|| value instanceof Float
|| value instanceof Double
|| value instanceof String
|| value instanceof Type
|| value instanceof byte[]
|| value instanceof boolean[]
|| value instanceof char[]
|| value instanceof short[]
|| value instanceof int[]
|| value instanceof long[]
|| value instanceof float[]
|| value instanceof double[])) {
throw new IllegalArgumentException("Invalid annotation value");
}
if (value instanceof Type && ((Type) value).getSort() == Type.METHOD) {
throw new IllegalArgumentException("Invalid annotation value");
}
super.visit(name, value);
}
@Override
public void visitVarInsn(final int opcode, final int var) {
switch (opcode) {
case Opcodes.ILOAD:
load(var, Type.INT_TYPE);
break;
case Opcodes.LLOAD:
load(var, Type.LONG_TYPE);
break;
case Opcodes.FLOAD:
load(var, Type.FLOAT_TYPE);
break;
case Opcodes.DLOAD:
load(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ALOAD:
load(var, OBJECT_TYPE);
break;
case Opcodes.ISTORE:
store(var, Type.INT_TYPE);
break;
case Opcodes.LSTORE:
store(var, Type.LONG_TYPE);
break;
case Opcodes.FSTORE:
store(var, Type.FLOAT_TYPE);
break;
case Opcodes.DSTORE:
store(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ASTORE:
store(var, OBJECT_TYPE);
break;
case Opcodes.RET:
ret(var);
break;
default:
throw new IllegalArgumentException();
}
}
/**
* Generates the instructions to unbox the top stack value. This value is replaced by its unboxed
* equivalent on top of the stack.
*
* @param type the type of the top stack value.
*/
public void unbox(final Type type) {
Type boxedType = NUMBER_TYPE;
Method unboxMethod;
switch (type.getSort()) {
case Type.VOID:
return;
case Type.CHAR:
boxedType = CHARACTER_TYPE;
unboxMethod = CHAR_VALUE;
break;
case Type.BOOLEAN:
boxedType = BOOLEAN_TYPE;
unboxMethod = BOOLEAN_VALUE;
break;
case Type.DOUBLE:
unboxMethod = DOUBLE_VALUE;
break;
case Type.FLOAT:
unboxMethod = FLOAT_VALUE;
break;
case Type.LONG:
unboxMethod = LONG_VALUE;
break;
case Type.INT:
case Type.SHORT:
case Type.BYTE:
unboxMethod = INT_VALUE;
break;
default:
unboxMethod = null;
break;
}
if (unboxMethod == null) {
checkCast(type);
} else {
checkCast(boxedType);
invokeVirtual(boxedType, unboxMethod);
}
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
int argumentSize = (Type.getArgumentsAndReturnSizes(desc) >> 2);
InferredType receiverType = getTypeOfOperandFromTop(argumentSize - 1);
if (receiverType.isUninitialized()) {
InferredType realType = InferredType.create('L' + owner + ';');
replaceUninitializedTypeInStack(receiverType, realType);
}
}
switch (opcode) {
case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE:
popDescriptor(desc);
if (opcode != Opcodes.INVOKESTATIC) {
pop(); // Pop receiver.
}
pushDescriptor(desc);
break;
default:
throw new RuntimeException(
String.format(
"Unhandled opcode %s, owner=%s, name=%s, desc=%s, itf=%s",
opcode, owner, name, desc, itf));
}
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
private static List<AdviceParameter> getAdviceParameters(
Map<Integer, List<Type>> parameterAnnotationTypes, Type[] parameterTypes,
List<Type> validBindAnnotationTypes, Type adviceAnnotationType)
throws AdviceConstructionException {
List<AdviceParameter> parameters = Lists.newArrayList();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].equals(ThreadContextType)) {
parameters.add(ImmutableAdviceParameter.builder()
.kind(ParameterKind.THREAD_CONTEXT)
.type(ThreadContextType)
.build());
continue;
}
if (parameterTypes[i].equals(OptionalThreadContextType)) {
parameters.add(ImmutableAdviceParameter.builder()
.kind(ParameterKind.OPTIONAL_THREAD_CONTEXT)
.type(OptionalThreadContextType)
.build());
continue;
}
Type validBindAnnotationType = getValidBindAnnotationType(
checkNotNull(parameterAnnotationTypes.get(i)), validBindAnnotationTypes);
if (validBindAnnotationType == null) {
// no valid bind annotations found, provide a good error message
List<String> validBindAnnotationNames = Lists.newArrayList();
for (Type annotationType : validBindAnnotationTypes) {
validBindAnnotationNames.add("@" + annotationType.getClassName());
}
throw new AdviceConstructionException("All parameters to @"
+ adviceAnnotationType.getClassName() + " must be annotated with one"
+ " of " + Joiner.on(", ").join(validBindAnnotationNames));
}
parameters.add(getAdviceParameter(validBindAnnotationType, parameterTypes[i]));
}
return parameters;
}
public static void processIndy(ClassNode classNode, String methodName, InvokeDynamicInsnNode indy) {
MethodNode indyWrapper = new MethodNode(Opcodes.ASM7,
Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC,
methodName, indy.desc, null, new String[0]);
int localVarsPosition = 0;
for (Type arg : Type.getArgumentTypes(indy.desc)) {
indyWrapper.instructions.add(new VarInsnNode(arg.getOpcode(Opcodes.ILOAD), localVarsPosition));
localVarsPosition += arg.getSize();
}
indyWrapper.instructions.add(new InvokeDynamicInsnNode(indy.name, indy.desc, indy.bsm, indy.bsmArgs));
indyWrapper.instructions.add(new InsnNode(Opcodes.ARETURN));
classNode.methods.add(indyWrapper);
}
/**
* add Throws statement with int param 2
*/
private void throwExIntParam(MethodVisitor mv, Class<?> exCls) {
String exSig = Type.getInternalName(exCls);
mv.visitTypeInsn(NEW, exSig);
mv.visitInsn(DUP);
mv.visitLdcInsn("mapping " + this.className + " failed to map field:");
mv.visitVarInsn(ILOAD, 2);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;");
mv.visitMethodInsn(INVOKESPECIAL, exSig, "<init>", "(Ljava/lang/String;)V");
mv.visitInsn(ATHROW);
}
public Type translateMethodType(Type methodType) {
Type[] translated =
translateTypes(
mcClasses,
Lists.asList(methodType.getReturnType(), methodType.getArgumentTypes())
.toArray(new Type[]{}));
return Type.getMethodType(translated[0], Arrays.copyOfRange(translated, 1, translated.length));
}