diff --git a/agent/src/main/java/com/alibaba/testable/agent/handler/ClassHandler.java b/agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java similarity index 91% rename from agent/src/main/java/com/alibaba/testable/agent/handler/ClassHandler.java rename to agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java index 24ac6e6..374118c 100644 --- a/agent/src/main/java/com/alibaba/testable/agent/handler/ClassHandler.java +++ b/agent/src/main/java/com/alibaba/testable/agent/handler/BaseClassHandler.java @@ -10,7 +10,7 @@ import java.io.IOException; /** * @author flin */ -abstract public class ClassHandler implements Opcodes { +abstract public class BaseClassHandler implements Opcodes { public byte[] getBytes(String className) throws IOException { ClassReader cr = new ClassReader(className); diff --git a/agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java b/agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java index 4437440..29fe953 100644 --- a/agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java +++ b/agent/src/main/java/com/alibaba/testable/agent/handler/SourceClassHandler.java @@ -4,20 +4,17 @@ import com.alibaba.testable.agent.constant.ConstPool; import com.alibaba.testable.agent.model.MethodInfo; import com.alibaba.testable.agent.util.ClassUtil; import com.alibaba.testable.agent.util.CollectionUtil; -import com.alibaba.testable.agent.util.StringUtil; import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; import org.objectweb.asm.tree.*; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Set; /** * @author flin */ -public class SourceClassHandler extends ClassHandler { +public class SourceClassHandler extends BaseClassHandler { private static final String CONSTRUCTOR = ""; private final List injectMethods; diff --git a/agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java b/agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java index 6336aeb..211894f 100644 --- a/agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java +++ b/agent/src/main/java/com/alibaba/testable/agent/handler/TestClassHandler.java @@ -11,7 +11,7 @@ import java.util.List; /** * @author flin */ -public class TestClassHandler extends ClassHandler { +public class TestClassHandler extends BaseClassHandler { private static final List TEST_ANNOTATIONS = new ArrayList(); diff --git a/core/src/main/java/com/alibaba/testable/core/constant/ConstPool.java b/core/src/main/java/com/alibaba/testable/core/constant/ConstPool.java index 7e57555..3d225d7 100644 --- a/core/src/main/java/com/alibaba/testable/core/constant/ConstPool.java +++ b/core/src/main/java/com/alibaba/testable/core/constant/ConstPool.java @@ -5,16 +5,8 @@ package com.alibaba.testable.core.constant; */ public final class ConstPool { - public static final String TYPE_UTIL = "com.alibaba.testable.core.util.TypeUtil"; - public static final String CLASS_SUBSTITUTION = TYPE_UTIL + ".TestableSubstitution"; - public static final String METHOD_ADD_TO_CON_POLL = TYPE_UTIL + ".addToConstructorPool"; - public static final String METHOD_ADD_TO_MEM_POOL = TYPE_UTIL + ".addToMemberMethodPool"; - public static final String CLASS_OF_TYPE = "class"; - public static final String TYPE_CLASS = "Class"; - public static final String REF_THIS = "this"; public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor"; public static final String ANNOTATION_TESTABLE_INJECT = "com.alibaba.testable.core.annotation.TestableInject"; - public static final String TESTABLE_SETUP_METHOD_NAME = "testableSetup"; public static final String TESTABLE_REF_FIELD_NAME = "_testableInternalRef"; public static final String TEST_POSTFIX = "Test"; diff --git a/core/src/main/java/com/alibaba/testable/core/generator/TestSetupMethodGenerator.java b/core/src/main/java/com/alibaba/testable/core/generator/TestSetupMethodGenerator.java deleted file mode 100644 index f73fcd5..0000000 --- a/core/src/main/java/com/alibaba/testable/core/generator/TestSetupMethodGenerator.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.alibaba.testable.core.generator; - -import com.alibaba.testable.core.model.TestableContext; -import com.alibaba.testable.core.constant.ConstPool; -import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.tree.JCTree.*; -import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.Pair; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -/** - * Generate test class setup method definition - * - * @author flin - */ -public class TestSetupMethodGenerator extends BaseGenerator { - - /** - * MethodName -> (ResultType -> ParameterTypes) - */ - public ListBuffer>>> injectMethods = new ListBuffer<>(); - public final ListBuffer memberMethods = new ListBuffer<>(); - - public TestSetupMethodGenerator(TestableContext cx) { - super(cx); - } - - public JCMethodDecl fetch() { - JCModifiers mods = cx.treeMaker.Modifiers(Modifier.PUBLIC); - return cx.treeMaker.MethodDef(mods, cx.names.fromString(ConstPool.TESTABLE_SETUP_METHOD_NAME), - cx.treeMaker.Type(new Type.JCVoidType()), List.nil(), - List.nil(), List.nil(), testableSetupBlock(), null); - } - - private JCBlock testableSetupBlock() { - ListBuffer statements = new ListBuffer<>(); - for (Pair>> m : injectMethods.toList()) { - if (isMemberMethod(m)) { - statements.append(addToPoolStatement(m, ConstPool.METHOD_ADD_TO_MEM_POOL)); - } else { - statements.append(addToPoolStatement(m, ConstPool.METHOD_ADD_TO_CON_POLL)); - } - } - return cx.treeMaker.Block(0, statements.toList()); - } - - private boolean isMemberMethod(Pair>> m) { - for (Method method : memberMethods) { - if (method.getName().equals(m.fst.toString()) && parameterEquals(m.snd.snd, method.getParameterTypes())) { - return true; - } - } - return false; - } - - private boolean parameterEquals(List injectMethodArgs, Class[] memberMethodArgs) { - if (injectMethodArgs.length() != memberMethodArgs.length) { - return false; - } - for (int i = 0; i < injectMethodArgs.length(); i++) { - if (!memberMethodArgs[i].getName().equals(((JCFieldAccess)injectMethodArgs.get(i)).selected.type - .toString())) { - return false; - } - } - return true; - } - - private JCStatement addToPoolStatement(Pair>> m, String addPoolMethod) { - JCExpression pool = nameToExpression(ConstPool.CLASS_SUBSTITUTION); - JCExpression classType = m.snd.fst; - JCExpression methodName = cx.treeMaker.Literal(m.fst.toString()); - JCExpression parameterTypes = cx.treeMaker.NewArray(cx.treeMaker.Ident(cx.names.fromString(ConstPool.TYPE_CLASS)), - List.nil(), m.snd.snd); - JCExpression thisIns = cx.treeMaker.Ident(cx.names.fromString(ConstPool.REF_THIS)); - JCNewClass poolClass = cx.treeMaker.NewClass(null, List.nil(), pool, - List.of(classType, methodName, parameterTypes, thisIns), null); - JCExpression addInjectMethod = nameToExpression(addPoolMethod); - JCMethodInvocation apply = cx.treeMaker.Apply(List.nil(), addInjectMethod, - List.from(new JCExpression[] {poolClass})); - return cx.treeMaker.Exec(apply); - } - -} diff --git a/core/src/main/java/com/alibaba/testable/core/translator/EnableTestableTranslator.java b/core/src/main/java/com/alibaba/testable/core/translator/EnableTestableTranslator.java index 77377ff..19a6319 100644 --- a/core/src/main/java/com/alibaba/testable/core/translator/EnableTestableTranslator.java +++ b/core/src/main/java/com/alibaba/testable/core/translator/EnableTestableTranslator.java @@ -1,21 +1,18 @@ package com.alibaba.testable.core.translator; +import com.alibaba.testable.core.constant.ConstPool; import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator; -import com.alibaba.testable.core.generator.TestSetupMethodGenerator; import com.alibaba.testable.core.generator.TestableRefFieldGenerator; import com.alibaba.testable.core.model.TestableContext; -import com.alibaba.testable.core.constant.ConstPool; import com.alibaba.testable.core.util.TypeUtil; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.Pair; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Arrays; /** * Travel AST @@ -24,21 +21,17 @@ import java.util.Arrays; */ public class EnableTestableTranslator extends BaseTranslator { - private final TestableContext cx; private final String testClassName; private final String sourceClassName; private final ListBuffer sourceClassIns = new ListBuffer<>(); private final ListBuffer privateOrFinalFields = new ListBuffer<>(); private final ListBuffer privateMethods = new ListBuffer<>(); - private final TestSetupMethodGenerator testSetupMethodGenerator; private final PrivateAccessStatementGenerator privateAccessStatementGenerator; private final TestableRefFieldGenerator testableRefFieldGenerator; public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) { this.testClassName = testClassName; this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length()); - this.cx = cx; - this.testSetupMethodGenerator = new TestSetupMethodGenerator(cx); this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx); this.testableRefFieldGenerator = new TestableRefFieldGenerator(cx, pkgName + "." + testClassName); try { @@ -55,7 +48,6 @@ public class EnableTestableTranslator extends BaseTranslator { privateMethods.add(m.getName()); } } - testSetupMethodGenerator.memberMethods.addAll(Arrays.asList(cls.getDeclaredMethods())); } catch (Exception e) { e.printStackTrace(); } @@ -93,13 +85,6 @@ public class EnableTestableTranslator extends BaseTranslator { for (JCAnnotation a : jcMethodDecl.mods.annotations) { if (a.type != null && ConstPool.ANNOTATION_TESTABLE_INJECT.equals(a.type.tsym.toString())) { TypeUtil.toPublicFlags(jcMethodDecl.getModifiers()); - ListBuffer args = new ListBuffer<>(); - for (JCVariableDecl p : jcMethodDecl.params) { - args.add(cx.treeMaker.Select(p.vartype, cx.names.fromString(ConstPool.CLASS_OF_TYPE))); - } - JCExpression retType = jcMethodDecl.restype == null ? null : - cx.treeMaker.Select(jcMethodDecl.restype, cx.names.fromString(ConstPool.CLASS_OF_TYPE)); - testSetupMethodGenerator.injectMethods.add(Pair.of(jcMethodDecl.name, Pair.of(retType, args.toList()))); } } super.visitMethodDef(jcMethodDecl); @@ -114,7 +99,6 @@ public class EnableTestableTranslator extends BaseTranslator { if (jcClassDecl.name.toString().equals(testClassName)) { ListBuffer ndefs = new ListBuffer<>(); ndefs.addAll(jcClassDecl.defs); - ndefs.add(testSetupMethodGenerator.fetch()); ndefs.add(testableRefFieldGenerator.fetch()); jcClassDecl.defs = ndefs.toList(); } diff --git a/core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java b/core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java index 8aa4dd3..ece39d9 100644 --- a/core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java +++ b/core/src/main/java/com/alibaba/testable/core/util/TestableUtil.java @@ -1,17 +1,23 @@ package com.alibaba.testable.core.util; +import com.alibaba.testable.core.constant.ConstPool; + /** * @author flin */ public class TestableUtil { - private static final String TESTABLE_NE = "n.e"; + public static String currentMemberMethodName(Object testClassRef) { + return currentMemberMethodName(testClassRef.getClass()); + } - public static String currentMemberMethodName() { - StackTraceElement[] stack = Thread.currentThread().getStackTrace(); - for (int i = 0; i < stack.length; i++) { - if (stack[i].getClassName().equals(TESTABLE_NE)) { - return stack[i + 1].getMethodName(); + public static String currentMemberMethodName(Class testClass) { + StackTraceElement[] stack = getMainThread().getStackTrace(); + String testClassName = getRealClassName(testClass); + String sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length()); + for (int i = stack.length - 1; i >= 0; i--) { + if (stack[i].getClassName().equals(sourceClassName)) { + return stack[i].getMethodName(); } } return ""; @@ -21,7 +27,7 @@ public class TestableUtil { return currentTestCaseName(testClassRef.getClass()); } - public static String currentTestCaseName(Class testClass) { + public static String currentTestCaseName(Class testClass) { StackTraceElement[] stack = getMainThread().getStackTrace(); String testClassName = getRealClassName(testClass); for (int i = stack.length - 1; i >= 0; i--) { @@ -32,7 +38,7 @@ public class TestableUtil { return ""; } - private static String getRealClassName(Class testClass) { + private static String getRealClassName(Class testClass) { String className = testClass.getName(); int posOfInnerClass = className.lastIndexOf('$'); return posOfInnerClass > 0 ? className.substring(0, posOfInnerClass) : className; diff --git a/core/src/main/java/com/alibaba/testable/core/util/TypeUtil.java b/core/src/main/java/com/alibaba/testable/core/util/TypeUtil.java index 5988366..b86a8a2 100644 --- a/core/src/main/java/com/alibaba/testable/core/util/TypeUtil.java +++ b/core/src/main/java/com/alibaba/testable/core/util/TypeUtil.java @@ -22,126 +22,11 @@ public class TypeUtil { modifiers.flags |= Modifier.PUBLIC; } - /** - * Information of substitution method - */ - public static class TestableSubstitution { - public Class type; // target instance type to new / method return type - public Class[] parameterTypes; // constructor parameter types / member method parameter types - public Object targetObject; // object which provides substitution / object which provides substitution - public String methodName; // substitution method name / original member method name - - public TestableSubstitution(Class type, String methodName, Class[] parameterTypes, Object targetObject) { - this.type = type; - this.methodName = methodName; - this.parameterTypes = parameterTypes; - this.targetObject = targetObject; - } - } - - private static List mockNewPool = new ArrayList<>(); - private static List mockMemberPool = new ArrayList<>(); - - /** - * add item to constructor pool - */ - public static void addToConstructorPool(TestableSubstitution substitution) { - mockNewPool.add(substitution); - } - - /** - * add item to method pool - */ - public static void addToMemberMethodPool(TestableSubstitution substitution) { - mockMemberPool.add(substitution); - } - - /** - * substitution entry for new - */ - public static T wrapNew(Class classType, Object... parameters) { - Class[] cs = TypeUtil.getClassesFromObjects(parameters); - if (!mockNewPool.isEmpty()) { - try { - TestableSubstitution pi = getFromConstructorPool(classType, cs); - if (pi != null) { - Method m = pi.targetObject.getClass().getDeclaredMethod(pi.methodName, pi.parameterTypes); - m.setAccessible(true); - return (T)m.invoke(pi.targetObject, parameters); - } - } catch (Exception e) { - return null; - } - } - try { - Constructor c = TypeUtil.getConstructorByParameterTypes(classType.getConstructors(), cs); - if (c != null) { - return (T)c.newInstance(parameters); - } - } catch (Exception e) { - return null; - } - return null; - } - - /** - * substitution entry for member call - */ - public static T wrapCall(Object targetObject, String methodName, Object... parameters) { - Class[] cs = TypeUtil.getClassesFromObjects(parameters); - if (!mockMemberPool.isEmpty()) { - try { - TestableSubstitution pi = getFromMemberMethodPool(methodName, cs); - if (pi != null) { - Method m = pi.targetObject.getClass().getDeclaredMethod(pi.methodName, pi.parameterTypes); - m.setAccessible(true); - return (T)m.invoke(pi.targetObject, parameters); - } - } catch (Exception e) { - return null; - } - } - try { - Method m = TypeUtil.getMethodByNameAndParameterTypes(targetObject.getClass().getDeclaredMethods(), methodName, cs); - if (m != null) { - m.setAccessible(true); - return (T)m.invoke(targetObject, parameters); - } - } catch (Exception e) { - return null; - } - return null; - } - - /** - * get from method pool by key - */ - private static TestableSubstitution getFromMemberMethodPool(String methodName, Class[] parameterTypes) { - for (TestableSubstitution f : mockMemberPool) { - if (f.methodName.equals(methodName) && TypeUtil.typeEquals(f.parameterTypes, parameterTypes)) { - return f; - } - } - return null; - } - - /** - * get from constructor pool by key - */ - private static TestableSubstitution getFromConstructorPool(Class type, Class[] parameterTypes) { - for (TestableSubstitution w : mockNewPool) { - if (w.type.equals(type) && TypeUtil.typeEquals(w.parameterTypes, parameterTypes)) { - return w; - } - } - return null; - } - /** * get classes of parameter objects */ - public static Class[] getClassesFromObjects(Object[] parameterObjects) { - Class[] cs = new Class[parameterObjects.length]; + public static Class[] getClassesFromObjects(Object[] parameterObjects) { + Class[] cs = new Class[parameterObjects.length]; for (int i = 0; i < cs.length; i++) { cs[i] = parameterObjects[i].getClass(); } @@ -153,7 +38,7 @@ public class TypeUtil { */ public static Method getMethodByNameAndParameterTypes(Method[] availableMethods, String methodName, - Class[] parameterTypes) { + Class[] parameterTypes) { for (Method m : availableMethods) { if (m.getName().equals(methodName) && typeEquals(m.getParameterTypes(), parameterTypes)) { @@ -164,22 +49,9 @@ public class TypeUtil { } /** - * get constructor by parameter matching + * type equals */ - public static Constructor getConstructorByParameterTypes(Constructor[] constructors, - Class[] parameterTypes) { - for (Constructor c : constructors) { - if (typeEquals(c.getParameterTypes(), parameterTypes)) { - return c; - } - } - return null; - } - - /** - * type equeals - */ - public static boolean typeEquals(Class[] classesLeft, Class[] classesRight) { + public static boolean typeEquals(Class[] classesLeft, Class[] classesRight) { if (classesLeft.length != classesRight.length) { return false; } @@ -197,7 +69,7 @@ public class TypeUtil { * @param factTypes fact types (can be primary type) * @param userTypes user types */ - private static boolean fuzzyEqual(Class factTypes, Class userTypes) { + private static boolean fuzzyEqual(Class factTypes, Class userTypes) { return (factTypes.equals(int.class) && userTypes.equals(Integer.class)) || (factTypes.equals(long.class) && userTypes.equals(Long.class)) || (factTypes.equals(short.class) && userTypes.equals(Short.class)) || diff --git a/core/src/main/java/n/e.java b/core/src/main/java/n/e.java deleted file mode 100644 index cee93cc..0000000 --- a/core/src/main/java/n/e.java +++ /dev/null @@ -1,121 +0,0 @@ -package n; - -import static com.alibaba.testable.core.util.TypeUtil.wrapCall; -import static com.alibaba.testable.core.util.TypeUtil.wrapNew; - -public final class e { - - public static T w(Class ct) { - return wrapNew(ct); - } - - public static T w(Class ct, Object a1) { - return wrapNew(ct, a1); - } - - public static T w(Class ct, Object a1, Object a2) { - return wrapNew(ct, a1, a2); - } - - public static T w(Class ct, Object a1, Object a2, Object a3) { - return wrapNew(ct, a1, a2, a3); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4) { - return wrapNew(ct, a1, a2, a3, a4); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5) { - return wrapNew(ct, a1, a2, a3, a4, a5); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10, Object a11) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); - } - - public static T w(Class ct, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10, Object a11, Object a12) { - return wrapNew(ct, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); - } - - public static T f(Object o, String mn) { - return wrapCall(o, mn); - } - - public static T f(Object o, String mn, Object a1) { - return wrapCall(o, mn, a1); - } - - public static T f(Object o, String mn, Object a1, Object a2) { - return wrapCall(o, mn, a1, a2); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3) { - return wrapCall(o, mn, a1, a2, a3); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4) { - return wrapCall(o, mn, a1, a2, a3, a4); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5) { - return wrapCall(o, mn, a1, a2, a3, a4, a5); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10, Object a11) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); - } - - public static T f(Object o, String mn, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, - Object a8, Object a9, Object a10, Object a11, Object a12) { - return wrapCall(o, mn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); - } -}