Path: blob/master/test/jdk/java/lang/invoke/LFCaching/TestMethods.java
41152 views
/*1* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import test.java.lang.invoke.lib.Helper;2425import java.lang.invoke.MethodHandle;26import java.lang.invoke.MethodHandles;27import java.lang.invoke.MethodType;28import java.lang.reflect.Array;29import java.util.ArrayList;30import java.util.HashMap;31import java.util.List;32import java.util.Map;3334/**35* Enumeration containing information about methods from36* {@code j.l.i.MethodHandles} class that are used for testing lambda forms37* caching.38*39* @author kshefov40*/41public enum TestMethods {4243FOLD_ARGUMENTS("foldArguments") {44@Override45public Map<String, Object> getTestCaseData() {46Map<String, Object> data = new HashMap<>();47int desiredArity = Helper.RNG.nextInt(super.maxArity);48MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);49data.put("mtTarget", mtTarget);50// Arity after reducing because of long and double take 2 slots.51int realArity = mtTarget.parameterCount();52int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);53data.put("modifierMHArgNum", modifierMHArgNum);54Class<?> combinerReturnType;55if (realArity == 0) {56combinerReturnType = void.class;57} else {58combinerReturnType = Helper.RNG.nextBoolean() ?59void.class : mtTarget.parameterType(0);60}61data.put("combinerReturnType", combinerReturnType);62return data;63}6465@Override66protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)67throws NoSuchMethodException, IllegalAccessException {68MethodType mtTarget = (MethodType) data.get("mtTarget");69Class<?> combinerReturnType = (Class) data.get("combinerReturnType");70int modifierMHArgNum = (int) data.get("modifierMHArgNum");71MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),72mtTarget.parameterList(), kind);73Class<?> rType = mtTarget.returnType();74int combListStart = (combinerReturnType == void.class) ? 0 : 1;75if (modifierMHArgNum < combListStart) {76modifierMHArgNum = combListStart;77}78MethodHandle combiner = TestMethods.methodHandleGenerator(combinerReturnType,79mtTarget.parameterList().subList(combListStart,80modifierMHArgNum), kind);81return MethodHandles.foldArguments(target, combiner);82}83},84DROP_ARGUMENTS("dropArguments") {85@Override86public Map<String, Object> getTestCaseData() {87Map<String, Object> data = new HashMap<>();88int desiredArity = Helper.RNG.nextInt(super.maxArity);89MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);90data.put("mtTarget", mtTarget);91// Arity after reducing because of long and double take 2 slots.92int realArity = mtTarget.parameterCount();93int dropArgsPos = Helper.RNG.nextInt(realArity + 1);94data.put("dropArgsPos", dropArgsPos);95MethodType mtDropArgs = TestMethods.randomMethodTypeGenerator(96Helper.RNG.nextInt(super.maxArity - realArity));97data.put("mtDropArgs", mtDropArgs);98return data;99}100101@Override102protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)103throws NoSuchMethodException, IllegalAccessException {104MethodType mtTarget = (MethodType) data.get("mtTarget");105MethodType mtDropArgs = (MethodType) data.get("mtDropArgs");106int dropArgsPos = (int) data.get("dropArgsPos");107MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),108mtTarget.parameterList(), kind);109int mtTgtSlotsCount = TestMethods.argSlotsCount(mtTarget);110int mtDASlotsCount = TestMethods.argSlotsCount(mtDropArgs);111List<Class<?>> fakeParList;112if (mtTgtSlotsCount + mtDASlotsCount > super.maxArity - 1) {113fakeParList = TestMethods.reduceArgListToSlotsCount(mtDropArgs.parameterList(),114super.maxArity - mtTgtSlotsCount - 1);115} else {116fakeParList = mtDropArgs.parameterList();117}118return MethodHandles.dropArguments(target, dropArgsPos, fakeParList);119}120},121EXPLICIT_CAST_ARGUMENTS("explicitCastArguments", Helper.MAX_ARITY / 2) {122@Override123public Map<String, Object> getTestCaseData() {124Map<String, Object> data = new HashMap<>();125int desiredArity = Helper.RNG.nextInt(super.maxArity);126MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);127data.put("mtTarget", mtTarget);128// Arity after reducing because of long and double take 2 slots.129int realArity = mtTarget.parameterCount();130MethodType mtExcplCastArgs = TestMethods.randomMethodTypeGenerator(realArity);131if (mtTarget.returnType() == void.class) {132mtExcplCastArgs = MethodType.methodType(void.class,133mtExcplCastArgs.parameterArray());134}135if (mtExcplCastArgs.returnType() == void.class) {136mtExcplCastArgs = MethodType.methodType(mtTarget.returnType(),137mtExcplCastArgs.parameterArray());138}139data.put("mtExcplCastArgs", mtExcplCastArgs);140return data;141}142143@Override144protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)145throws NoSuchMethodException, IllegalAccessException {146MethodType mtTarget = (MethodType) data.get("mtTarget");147MethodType mtExcplCastArgs = (MethodType) data.get("mtExcplCastArgs");148MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),149mtTarget.parameterList(), kind);150return MethodHandles.explicitCastArguments(target, mtExcplCastArgs);151}152},153FILTER_ARGUMENTS("filterArguments", Helper.MAX_ARITY / 2) {154@Override155public Map<String, Object> getTestCaseData() {156Map<String, Object> data = new HashMap<>();157int desiredArity = Helper.RNG.nextInt(super.maxArity);158MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);159data.put("mtTarget", mtTarget);160// Arity after reducing because of long and double take 2 slots.161int realArity = mtTarget.parameterCount();162int filterArgsPos = Helper.RNG.nextInt(realArity + 1);163data.put("filterArgsPos", filterArgsPos);164int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);165data.put("filtersArgsArrayLength", filtersArgsArrayLength);166MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);167data.put("mtFilter", mtFilter);168return data;169}170171@Override172protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)173throws NoSuchMethodException, IllegalAccessException {174MethodType mtTarget = (MethodType) data.get("mtTarget");175MethodType mtFilter = (MethodType) data.get("mtFilter");176int filterArgsPos = (int) data.get("filterArgsPos");177int filtersArgsArrayLength = (int) data.get("filtersArgsArrayLength");178MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),179mtTarget.parameterList(), kind);180MethodHandle[] filters = new MethodHandle[filtersArgsArrayLength];181for (int i = 0; i < filtersArgsArrayLength; i++) {182filters[i] = TestMethods.filterGenerator(mtFilter.parameterType(i),183mtTarget.parameterType(filterArgsPos + i), kind);184}185return MethodHandles.filterArguments(target, filterArgsPos, filters);186}187},188FILTER_RETURN_VALUE("filterReturnValue") {189@Override190public Map<String, Object> getTestCaseData() {191Map<String, Object> data = new HashMap<>();192int desiredArity = Helper.RNG.nextInt(super.maxArity);193MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);194data.put("mtTarget", mtTarget);195// Arity after reducing because of long and double take 2 slots.196int realArity = mtTarget.parameterCount();197int filterArgsPos = Helper.RNG.nextInt(realArity + 1);198int filtersArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - filterArgsPos);199MethodType mtFilter = TestMethods.randomMethodTypeGenerator(filtersArgsArrayLength);200data.put("mtFilter", mtFilter);201return data;202}203204@Override205protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)206throws NoSuchMethodException, IllegalAccessException {207MethodType mtTarget = (MethodType) data.get("mtTarget");208MethodType mtFilter = (MethodType) data.get("mtFilter");209MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),210mtTarget.parameterList(), kind);211MethodHandle filter = TestMethods.filterGenerator(mtTarget.returnType(),212mtFilter.returnType(), kind);213return MethodHandles.filterReturnValue(target, filter);214}215},216INSERT_ARGUMENTS("insertArguments", Helper.MAX_ARITY - 3) {217@Override218public Map<String, Object> getTestCaseData() {219Map<String, Object> data = new HashMap<>();220int desiredArity = Helper.RNG.nextInt(super.maxArity);221MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);222data.put("mtTarget", mtTarget);223// Arity after reducing because of long and double take 2 slots.224int realArity = mtTarget.parameterCount();225int insertArgsPos = Helper.RNG.nextInt(realArity + 1);226data.put("insertArgsPos", insertArgsPos);227int insertArgsArrayLength = Helper.RNG.nextInt(realArity + 1 - insertArgsPos);228MethodType mtInsertArgs = MethodType.methodType(void.class, mtTarget.parameterList()229.subList(insertArgsPos, insertArgsPos + insertArgsArrayLength));230data.put("mtInsertArgs", mtInsertArgs);231return data;232}233234@Override235protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)236throws NoSuchMethodException, IllegalAccessException {237MethodType mtTarget = (MethodType) data.get("mtTarget");238MethodType mtInsertArgs = (MethodType) data.get("mtInsertArgs");239int insertArgsPos = (int) data.get("insertArgsPos");240MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),241mtTarget.parameterList(), kind);242Object[] insertList = Helper.randomArgs(mtInsertArgs.parameterList());243return MethodHandles.insertArguments(target, insertArgsPos, insertList);244}245},246PERMUTE_ARGUMENTS("permuteArguments", Helper.MAX_ARITY / 2) {247@Override248public Map<String, Object> getTestCaseData() {249Map<String, Object> data = new HashMap<>();250int desiredArity = Helper.RNG.nextInt(super.maxArity);251MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);252// Arity after reducing because of long and double take 2 slots.253int realArity = mtTarget.parameterCount();254int[] permuteArgsReorderArray = new int[realArity];255int mtPermuteArgsNum = Helper.RNG.nextInt(Helper.MAX_ARITY);256mtPermuteArgsNum = mtPermuteArgsNum == 0 ? 1 : mtPermuteArgsNum;257MethodType mtPermuteArgs = TestMethods.randomMethodTypeGenerator(mtPermuteArgsNum);258mtTarget = mtTarget.changeReturnType(mtPermuteArgs.returnType());259for (int i = 0; i < realArity; i++) {260int mtPermuteArgsParNum = Helper.RNG.nextInt(mtPermuteArgs.parameterCount());261permuteArgsReorderArray[i] = mtPermuteArgsParNum;262mtTarget = mtTarget.changeParameterType(263i, mtPermuteArgs.parameterType(mtPermuteArgsParNum));264}265data.put("mtTarget", mtTarget);266data.put("permuteArgsReorderArray", permuteArgsReorderArray);267data.put("mtPermuteArgs", mtPermuteArgs);268return data;269}270271@Override272protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)273throws NoSuchMethodException, IllegalAccessException {274MethodType mtTarget = (MethodType) data.get("mtTarget");275MethodType mtPermuteArgs = (MethodType) data.get("mtPermuteArgs");276int[] permuteArgsReorderArray = (int[]) data.get("permuteArgsReorderArray");277MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),278mtTarget.parameterList(), kind);279return MethodHandles.permuteArguments(target, mtPermuteArgs, permuteArgsReorderArray);280}281},282THROW_EXCEPTION("throwException") {283@Override284public Map<String, Object> getTestCaseData() {285Map<String, Object> data = new HashMap<>();286int desiredArity = Helper.RNG.nextInt(super.maxArity);287MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);288data.put("mtTarget", mtTarget);289return data;290}291292@Override293protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {294MethodType mtTarget = (MethodType) data.get("mtTarget");295Class<?> rType = mtTarget.returnType();296return MethodHandles.throwException(rType, Exception.class297);298}299},300GUARD_WITH_TEST("guardWithTest") {301@Override302public Map<String, Object> getTestCaseData() {303Map<String, Object> data = new HashMap<>();304int desiredArity = Helper.RNG.nextInt(super.maxArity);305MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);306data.put("mtTarget", mtTarget);307// Arity after reducing because of long and double take 2 slots.308int realArity = mtTarget.parameterCount();309int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);310data.put("modifierMHArgNum", modifierMHArgNum);311return data;312}313314@Override315protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)316throws NoSuchMethodException, IllegalAccessException {317MethodType mtTarget = (MethodType) data.get("mtTarget");318int modifierMHArgNum = (int) data.get("modifierMHArgNum");319TestMethods.Kind targetKind;320TestMethods.Kind fallbackKind;321if (kind.equals(TestMethods.Kind.ONE)) {322targetKind = TestMethods.Kind.ONE;323fallbackKind = TestMethods.Kind.TWO;324} else {325targetKind = TestMethods.Kind.TWO;326fallbackKind = TestMethods.Kind.ONE;327}328MethodHandle target = TestMethods.methodHandleGenerator(mtTarget.returnType(),329mtTarget.parameterList(), targetKind);330MethodHandle fallback = TestMethods.methodHandleGenerator(mtTarget.returnType(),331mtTarget.parameterList(), fallbackKind);332MethodHandle test = TestMethods.methodHandleGenerator(boolean.class,333mtTarget.parameterList().subList(0, modifierMHArgNum), kind);334return MethodHandles.guardWithTest(test, target, fallback);335}336},337CATCH_EXCEPTION("catchException") {338@Override339public Map<String, Object> getTestCaseData() {340Map<String, Object> data = new HashMap<>();341int desiredArity = Helper.RNG.nextInt(super.maxArity);342MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);343data.put("mtTarget", mtTarget);344// Arity after reducing because of long and double take 2 slots.345int realArity = mtTarget.parameterCount();346int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);347data.put("modifierMHArgNum", modifierMHArgNum);348return data;349}350351@Override352protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)353throws NoSuchMethodException, IllegalAccessException {354MethodType mtTarget = (MethodType) data.get("mtTarget");355int modifierMHArgNum = (int) data.get("modifierMHArgNum");356MethodHandle target;357if (kind.equals(TestMethods.Kind.ONE)) {358target = TestMethods.methodHandleGenerator(mtTarget.returnType(),359mtTarget.parameterList(), TestMethods.Kind.ONE);360} else {361target = TestMethods.methodHandleGenerator(mtTarget.returnType(),362mtTarget.parameterList(), TestMethods.Kind.EXCEPT);363}364List<Class<?>> handlerParamList = new ArrayList<>(mtTarget.parameterCount() + 1);365handlerParamList.add(Exception.class);366handlerParamList.addAll(mtTarget.parameterList().subList(0, modifierMHArgNum));367MethodHandle handler = TestMethods.methodHandleGenerator(368mtTarget.returnType(), handlerParamList, TestMethods.Kind.TWO);369return MethodHandles.catchException(target, Exception.class, handler);370}371},372INVOKER("invoker", Helper.MAX_ARITY - 1) {373@Override374public Map<String, Object> getTestCaseData() {375Map<String, Object> data = new HashMap<>();376int desiredArity = Helper.RNG.nextInt(super.maxArity);377MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);378data.put("mtTarget", mtTarget);379return data;380}381382@Override383protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {384MethodType mtTarget = (MethodType) data.get("mtTarget");385return MethodHandles.invoker(mtTarget);386}387},388EXACT_INVOKER("exactInvoker", Helper.MAX_ARITY - 1) {389@Override390public Map<String, Object> getTestCaseData() {391Map<String, Object> data = new HashMap<>();392int desiredArity = Helper.RNG.nextInt(super.maxArity);393MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);394data.put("mtTarget", mtTarget);395return data;396}397398@Override399protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {400MethodType mtTarget = (MethodType) data.get("mtTarget");401return MethodHandles.exactInvoker(mtTarget);402}403},404SPREAD_INVOKER("spreadInvoker", Helper.MAX_ARITY - 1) {405@Override406public Map<String, Object> getTestCaseData() {407Map<String, Object> data = new HashMap<>();408int desiredArity = Helper.RNG.nextInt(super.maxArity);409MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);410data.put("mtTarget", mtTarget);411// Arity after reducing because of long and double take 2 slots.412int realArity = mtTarget.parameterCount();413int modifierMHArgNum = Helper.RNG.nextInt(realArity + 1);414data.put("modifierMHArgNum", modifierMHArgNum);415return data;416}417418@Override419protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {420MethodType mtTarget = (MethodType) data.get("mtTarget");421int modifierMHArgNum = (int) data.get("modifierMHArgNum");422return MethodHandles.spreadInvoker(mtTarget, modifierMHArgNum);423}424},425ARRAY_ELEMENT_GETTER("arrayElementGetter") {426@Override427public Map<String, Object> getTestCaseData() {428Map<String, Object> data = new HashMap<>();429int desiredArity = Helper.RNG.nextInt(super.maxArity);430MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);431data.put("mtTarget", mtTarget);432return data;433}434435@Override436protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {437MethodType mtTarget = (MethodType) data.get("mtTarget");438Class<?> rType = mtTarget.returnType();439if (rType == void.class) {440rType = Object.class;441}442return MethodHandles.arrayElementGetter(Array.newInstance(rType, 2).getClass());443}444},445ARRAY_ELEMENT_SETTER("arrayElementSetter") {446@Override447public Map<String, Object> getTestCaseData() {448Map<String, Object> data = new HashMap<>();449int desiredArity = Helper.RNG.nextInt(super.maxArity);450MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);451data.put("mtTarget", mtTarget);452return data;453}454455@Override456protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {457MethodType mtTarget = (MethodType) data.get("mtTarget");458Class<?> rType = mtTarget.returnType();459if (rType == void.class) {460rType = Object.class;461}462return MethodHandles.arrayElementSetter(Array.newInstance(rType, 2).getClass());463}464},465CONSTANT("constant") {466@Override467public Map<String, Object> getTestCaseData() {468Map<String, Object> data = new HashMap<>();469int desiredArity = Helper.RNG.nextInt(super.maxArity);470MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);471data.put("mtTarget", mtTarget);472return data;473}474475@Override476protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {477MethodType mtTarget = (MethodType) data.get("mtTarget");478Class<?> rType = mtTarget.returnType();479if (rType == void.class) {480rType = Object.class;481}482if (rType.equals(boolean.class)) {483// There should be the same return values because for default values there are special "zero" forms484return MethodHandles.constant(rType, true);485} else {486return MethodHandles.constant(rType, kind.getValue(rType));487}488}489},490IDENTITY("identity") {491@Override492public Map<String, Object> getTestCaseData() {493Map<String, Object> data = new HashMap<>();494int desiredArity = Helper.RNG.nextInt(super.maxArity);495MethodType mtTarget = TestMethods.randomMethodTypeGenerator(desiredArity);496data.put("mtTarget", mtTarget);497return data;498}499500@Override501protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind) {502MethodType mtTarget = (MethodType) data.get("mtTarget");503Class<?> rType = mtTarget.returnType();504if (rType == void.class) {505rType = Object.class;506}507return MethodHandles.identity(rType);508}509};510511/**512* Test method's name.513*/514public final String name;515516private final int maxArity;517518private TestMethods(String name, int maxArity) {519this.name = name;520this.maxArity = maxArity;521}522523private TestMethods(String name) {524this(name, Helper.MAX_ARITY);525}526527protected MethodHandle getMH(Map<String, Object> data, TestMethods.Kind kind)528throws NoSuchMethodException, IllegalAccessException {529throw new UnsupportedOperationException(530"TESTBUG: getMH method is not implemented for test method " + this);531}532533/**534* Creates an adapter method handle depending on a test method from535* MethodHandles class. Adapter is what is returned by the test method. This536* method is able to create two kinds of adapters, their type will be the537* same, but return values are different.538*539* @param data a Map containing data to create a method handle, can be540* obtained by {@link #getTestCaseData} method541* @param kind defines whether adapter ONE or adapter TWO will be542* initialized. Should be equal to TestMethods.Kind.ONE or543* TestMethods.Kind.TWO544* @return Method handle adapter that behaves according to545* TestMethods.Kind.ONE or TestMethods.Kind.TWO546* @throws java.lang.NoSuchMethodException547* @throws java.lang.IllegalAccessException548*/549public MethodHandle getTestCaseMH(Map<String, Object> data, TestMethods.Kind kind)550throws NoSuchMethodException, IllegalAccessException {551if (data == null) {552throw new Error(String.format("TESTBUG: Data for test method %s is not prepared",553this.name));554}555if (!kind.equals(TestMethods.Kind.ONE) && !kind.equals(TestMethods.Kind.TWO)) {556throw new IllegalArgumentException("TESTBUG: Wrong \"kind\" (" + kind557+ ") arg to getTestCaseMH function."558+ " Should be Kind.ONE or Kind.TWO");559}560return getMH(data, kind);561}562563/**564* Returns a data Map needed for {@link #getTestCaseMH} method.565*566* @return data Map needed for {@link #getTestCaseMH} method567*/568public Map<String, Object> getTestCaseData() {569throw new UnsupportedOperationException(570"TESTBUG: getTestCaseData method is not implemented for test method " + this);571}572573/**574* Enumeration used in methodHandleGenerator to define whether a MH returned575* by this method returns "2" in different type representations, "4", or576* throw an Exception.577*/578public static enum Kind {579580ONE(2),581TWO(4),582EXCEPT(0);583584private final int value;585586private Object getValue(Class<?> cl) {587return Helper.castToWrapper(value, cl);588}589590private MethodHandle getBasicMH(Class<?> rType)591throws NoSuchMethodException, IllegalAccessException {592MethodHandle result = null;593switch (this) {594case ONE:595case TWO:596if (rType.equals(void.class)) {597result = MethodHandles.lookup().findVirtual(Kind.class,598"returnVoid", MethodType.methodType(void.class));599result = MethodHandles.insertArguments(result, 0, this);600} else {601result = MethodHandles.constant(rType, getValue(rType));602}603break;604case EXCEPT:605result = MethodHandles.throwException(rType, Exception.class);606result = MethodHandles.insertArguments(result, 0, new Exception());607break;608}609return result;610}611612private void returnVoid() {613}614615private Kind(int value) {616this.value = value;617}618}619620/**621* Routine used to obtain a randomly generated method type.622*623* @param arity Arity of returned method type.624* @return MethodType generated randomly.625*/626private static MethodType randomMethodTypeGenerator(int arity) {627return Helper.randomMethodTypeGenerator(arity);628}629630/**631* Routine used to obtain a method handles of a given type an kind (return632* value).633*634* @param returnType Type of MH return value.635* @param argTypes Types of MH args.636* @param kind Defines whether the obtained MH returns "1" or "2".637* @return Method handle of the given type.638* @throws NoSuchMethodException639* @throws IllegalAccessException640*/641private static MethodHandle methodHandleGenerator(Class<?> returnType,642List<Class<?>> argTypes, TestMethods.Kind kind)643throws NoSuchMethodException, IllegalAccessException {644MethodHandle result;645result = kind.getBasicMH(returnType);646return Helper.addTrailingArgs(result, argTypes.size(), argTypes);647}648649/**650* Routine that generates filter method handles to test651* MethodHandles.filterArguments method.652*653* @param inputType Filter's argument type.654* @param returnType Filter's return type.655* @param kind Filter's return value definer.656* @return A filter method handle, that takes one argument.657* @throws NoSuchMethodException658* @throws IllegalAccessException659*/660private static MethodHandle filterGenerator(Class<?> inputType, Class<?> returnType,661TestMethods.Kind kind) throws NoSuchMethodException, IllegalAccessException {662MethodHandle tmpMH = kind.getBasicMH(returnType);663if (inputType.equals(void.class)) {664return tmpMH;665}666ArrayList<Class<?>> inputTypeList = new ArrayList<>(1);667inputTypeList.add(inputType);668return Helper.addTrailingArgs(tmpMH, 1, inputTypeList);669}670671private static int argSlotsCount(MethodType mt) {672int result = 0;673for (Class cl : mt.parameterArray()) {674if (cl.equals(long.class) || cl.equals(double.class)) {675result += 2;676} else {677result++;678}679}680return result;681}682683private static List<Class<?>> reduceArgListToSlotsCount(List<Class<?>> list,684int desiredSlotCount) {685List<Class<?>> result = new ArrayList<>(desiredSlotCount);686int count = 0;687for (Class<?> cl : list) {688if (count >= desiredSlotCount) {689break;690}691if (cl.equals(long.class) || cl.equals(double.class)) {692count += 2;693} else {694count++;695}696result.add(cl);697}698return result;699}700}701702703