< prev index next >

test/jdk/java/lang/invoke/MethodHandlesTest.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package test.java.lang.invoke;
  25 
  26 import org.junit.*;
  27 import test.java.lang.invoke.remote.RemoteExample;
  28 
  29 import java.lang.invoke.MethodHandle;
  30 import java.lang.invoke.MethodHandles;
  31 import java.lang.invoke.MethodHandles.Lookup;
  32 import java.lang.invoke.MethodType;
  33 import java.lang.reflect.Array;
  34 import java.lang.reflect.Field;
  35 import java.lang.reflect.Modifier;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collection;
  39 import java.util.Collections;
  40 import java.util.List;
  41 import java.util.stream.Stream;
  42 
  43 import static org.junit.Assert.*;
  44 
  45 /**
  46  *
  47  * @author jrose
  48  */
  49 public abstract class MethodHandlesTest {
  50 
  51     static final Class<?> THIS_CLASS = MethodHandlesTest.class;
  52     // How much output?
  53     static int verbosity = 0;
  54 
  55     static {
  56         String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbosity");
  57         if (vstr == null)
  58             vstr = System.getProperty(THIS_CLASS.getName()+".verbosity");
  59         if (vstr != null)  verbosity = Integer.parseInt(vstr);
  60     }
  61 


 545         assertEquals(s, x);
 546     }
 547 
 548     public static class HasFields {
 549         boolean iZ = false;
 550         byte iB = (byte)'B';
 551         short iS = (short)'S';
 552         char iC = 'C';
 553         int iI = 'I';
 554         long iJ = 'J';
 555         float iF = 'F';
 556         double iD = 'D';
 557         static boolean sZ = true;
 558         static byte sB = 1+(byte)'B';
 559         static short sS = 1+(short)'S';
 560         static char sC = 1+'C';
 561         static int sI = 1+'I';
 562         static long sJ = 1+'J';
 563         static float sF = 1+'F';
 564         static double sD = 1+'D';
 565 
 566         // final fields
 567         final boolean fiZ = false;
 568         final byte fiB = 2+(byte)'B';
 569         final short fiS = 2+(short)'S';
 570         final char fiC = 2+'C';
 571         final int fiI = 2+'I';
 572         final long fiJ = 2+'J';
 573         final float fiF = 2+'F';
 574         final double fiD = 2+'D';
 575         final static boolean fsZ = false;
 576         final static byte fsB = 3+(byte)'B';
 577         final static short fsS = 3+(short)'S';
 578         final static char fsC = 3+'C';
 579         final static int fsI = 3+'I';
 580         final static long fsJ = 3+'J';
 581         final static float fsF = 3+'F';
 582         final static double fsD = 3+'D';
 583 
 584         Object iL = 'L';
 585         String iR = "iR";
 586         static Object sL = 1+'L';
 587         static String sR = "sR";
 588         final Object fiL = 2+'L';
 589         final String fiR = "fiR";
 590         final static Object fsL = 3+'L';
 591         final static String fsR = "fsR";
 592 
 593         static final ArrayList<Object[]> STATIC_FIELD_CASES = new ArrayList<>();
 594         static final ArrayList<Object[]> INSTANCE_FIELD_CASES = new ArrayList<>();
 595         static {

 596             Object types[][] = {
 597                 {'L',Object.class}, {'R',String.class},
 598                 {'I',int.class}, {'J',long.class},
 599                 {'F',float.class}, {'D',double.class},
 600                 {'Z',boolean.class}, {'B',byte.class},
 601                 {'S',short.class}, {'C',char.class},
 602             };
 603             HasFields fields = new HasFields();
 604             for (Object[] t : types) {
 605                 for (int kind = 0; kind <= 1; kind++) {
 606                     boolean isStatic = (kind != 0);
 607                     ArrayList<Object[]> cases = isStatic ? STATIC_FIELD_CASES : INSTANCE_FIELD_CASES;
 608                     char btc = (Character)t[0];
 609                     String fname = (isStatic ? "s" : "i") + btc;
 610                     String finalFname = (isStatic ? "fs" : "fi") + btc;
 611                     Class<?> type = (Class<?>) t[1];
 612                     // non-final field
 613                     Field nonFinalField = getField(fname, type);
 614                     Object value = getValue(fields, nonFinalField);









 615                     if (type == float.class) {
 616                         float v = 'F';
 617                         if (isStatic)  v++;

 618                         assertTrue(value.equals(v));
 619                     }
 620                     assertTrue(isStatic == (Modifier.isStatic(nonFinalField.getModifiers())));
 621                     cases.add(new Object[]{ nonFinalField, value });
 622 
 623                     // setAccessible(true) on final field but static final field only has read access
 624                     Field finalField = getField(finalFname, type);
 625                     Object fvalue = getValue(fields, finalField);
 626                     finalField.setAccessible(true);
 627                     assertTrue(isStatic == (Modifier.isStatic(finalField.getModifiers())));
 628                     cases.add(new Object[]{ finalField, fvalue, Error.class});
 629                 }
 630             }
 631             INSTANCE_FIELD_CASES.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
 632             STATIC_FIELD_CASES.add(new Object[]{ new Object[]{ true,  HasFields.class, "bogus_sL", Object.class }, Error.class });
 633         }
 634 
 635         private static Field getField(String name, Class<?> type) {
 636             try {
 637                 Field field = HasFields.class.getDeclaredField(name);
 638                 assertTrue(name.equals(field.getName()));
 639                 assertTrue(type.equals(field.getType()));
 640                 return field;
 641             } catch (NoSuchFieldException | SecurityException ex) {
 642                 throw new InternalError("no field HasFields."+name);
 643             }
 644         }
 645 
 646         private static Object getValue(Object o, Field field) {
 647             try {
 648                 return field.get(o);
 649             } catch (IllegalArgumentException | IllegalAccessException ex) {
 650                 throw new InternalError("cannot fetch field HasFields."+field.getName());
 651             }
 652         }
 653 
 654         static Object[][] testCasesFor(int testMode) {
 655             Stream<Object[]> cases;
 656             if ((testMode & TEST_UNREFLECT) != 0) {
 657                 cases = Stream.concat(STATIC_FIELD_CASES.stream(), INSTANCE_FIELD_CASES.stream());
 658             } else if ((testMode & TEST_FIND_STATIC) != 0) {
 659                 cases = STATIC_FIELD_CASES.stream();
 660             } else if ((testMode & TEST_FIND_FIELD) != 0) {
 661                 cases = INSTANCE_FIELD_CASES.stream();
 662             } else {
 663                 throw new InternalError("unexpected test mode: " + testMode);
 664             }
 665             return cases.map(c -> mapTestCase(testMode, c)).toArray(Object[][]::new);
 666 
 667         }
 668 
 669         private static Object[] mapTestCase(int testMode, Object[] c) {
 670             // non-final fields (2-element) and final fields (3-element) if not TEST_SETTER
 671             if (c.length == 2 || (testMode & TEST_SETTER) == 0)
 672                 return c;
 673 
 674             // final fields (3-element)
 675             assertTrue((testMode & TEST_SETTER) != 0 && c[0] instanceof Field && c[2] == Error.class);
 676             if ((testMode & TEST_UNREFLECT) == 0)
 677                 return new Object[]{ c[0], c[2]};   // negative test case; can't set on final fields
 678 
 679             // unreflectSetter grants write access on instance final field if accessible flag is true
 680             // hence promote the negative test case to positive test case
 681             Field f = (Field) c[0];
 682             int mods = f.getModifiers();
 683             if (!Modifier.isFinal(mods) || (!Modifier.isStatic(mods) && f.isAccessible())) {
 684                 // positive test case
 685                 return new Object[]{ c[0], c[1] };
 686             } else {
 687                 // otherwise, negative test case
 688                 return new Object[]{ c[0], c[2]};
 689             }
 690         }
 691     }
 692 
 693     static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10, TEST_BOUND = 0x20, TEST_NPE = 0x40;
 694 
 695     static boolean testModeMatches(int testMode, boolean isStatic) {
 696         switch (testMode) {
 697         case TEST_FIND_STATIC:          return isStatic;
 698         case TEST_FIND_FIELD:           return !isStatic;
 699         case TEST_UNREFLECT:            return true;  // unreflect matches both
 700         }
 701         throw new InternalError("testMode="+testMode);
 702     }
 703 
 704     static class Callee {
 705         static Object id() { return called("id"); }
 706         static Object id(Object x) { return called("id", x); }
 707         static Object id(Object x, Object y) { return called("id", x, y); }
 708         static Object id(Object x, Object y, Object z) { return called("id", x, y, z); }
 709         static Object id(Object... vx) { return called("id", vx); }


   1 /*
   2  * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package test.java.lang.invoke;
  25 
  26 import org.junit.*;
  27 import test.java.lang.invoke.remote.RemoteExample;
  28 
  29 import java.lang.invoke.MethodHandle;
  30 import java.lang.invoke.MethodHandles;
  31 import java.lang.invoke.MethodHandles.Lookup;
  32 import java.lang.invoke.MethodType;
  33 import java.lang.reflect.Array;
  34 import java.lang.reflect.Field;
  35 import java.lang.reflect.Modifier;
  36 import java.util.ArrayList;
  37 import java.util.Arrays;
  38 import java.util.Collection;
  39 import java.util.Collections;
  40 import java.util.List;

  41 
  42 import static org.junit.Assert.*;
  43 
  44 /**
  45  *
  46  * @author jrose
  47  */
  48 public abstract class MethodHandlesTest {
  49 
  50     static final Class<?> THIS_CLASS = MethodHandlesTest.class;
  51     // How much output?
  52     static int verbosity = 0;
  53 
  54     static {
  55         String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbosity");
  56         if (vstr == null)
  57             vstr = System.getProperty(THIS_CLASS.getName()+".verbosity");
  58         if (vstr != null)  verbosity = Integer.parseInt(vstr);
  59     }
  60 


 544         assertEquals(s, x);
 545     }
 546 
 547     public static class HasFields {
 548         boolean iZ = false;
 549         byte iB = (byte)'B';
 550         short iS = (short)'S';
 551         char iC = 'C';
 552         int iI = 'I';
 553         long iJ = 'J';
 554         float iF = 'F';
 555         double iD = 'D';
 556         static boolean sZ = true;
 557         static byte sB = 1+(byte)'B';
 558         static short sS = 1+(short)'S';
 559         static char sC = 1+'C';
 560         static int sI = 1+'I';
 561         static long sJ = 1+'J';
 562         static float sF = 1+'F';
 563         static double sD = 1+'D';










 564         final static boolean fsZ = false;
 565         final static byte fsB = 2+(byte)'B';
 566         final static short fsS = 2+(short)'S';
 567         final static char fsC = 2+'C';
 568         final static int fsI = 2+'I';
 569         final static long fsJ = 2+'J';
 570         final static float fsF = 2+'F';
 571         final static double fsD = 2+'D';
 572 
 573         Object iL = 'L';
 574         String iR = "R";
 575         static Object sL = 'M';
 576         static String sR = "S";
 577         final static Object fsL = 'N';
 578         final static String fsR = "T";


 579 
 580         static final Object[][] CASES;

 581         static {
 582             ArrayList<Object[]> cases = new ArrayList<>();
 583             Object types[][] = {
 584                 {'L',Object.class}, {'R',String.class},
 585                 {'I',int.class}, {'J',long.class},
 586                 {'F',float.class}, {'D',double.class},
 587                 {'Z',boolean.class}, {'B',byte.class},
 588                 {'S',short.class}, {'C',char.class},
 589             };
 590             HasFields fields = new HasFields();
 591             for (Object[] t : types) {
 592                 for (int kind = 0; kind <= 2; kind++) {
 593                     boolean isStatic = (kind != 0);
 594                     boolean isFinal  = (kind == 2);
 595                     char btc = (Character)t[0];
 596                     String name = (isStatic ? "s" : "i") + btc;
 597                     if (isFinal) name = "f" + name;
 598                     Class<?> type = (Class<?>) t[1];
 599                     Object value;
 600                     Field field;
 601                     try {
 602                         field = HasFields.class.getDeclaredField(name);
 603                     } catch (NoSuchFieldException | SecurityException ex) {
 604                         throw new InternalError("no field HasFields."+name);
 605                     }
 606                     try {
 607                         value = field.get(fields);
 608                     } catch (IllegalArgumentException | IllegalAccessException ex) {
 609                         throw new InternalError("cannot fetch field HasFields."+name);
 610                     }
 611                     if (type == float.class) {
 612                         float v = 'F';
 613                         if (isStatic)  v++;
 614                         if (isFinal)   v++;
 615                         assertTrue(value.equals(v));
 616                     }
 617                     if (isFinal && isStatic) field.setAccessible(true);
 618                     assertTrue(name.equals(field.getName()));
 619                     assertTrue(type.equals(field.getType()));
 620                     assertTrue(isStatic == (Modifier.isStatic(field.getModifiers())));
 621                     assertTrue(isFinal  == (Modifier.isFinal(field.getModifiers())));
 622                     cases.add(new Object[]{ field, value });



 623                 }
 624             }
 625             cases.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
 626             cases.add(new Object[]{ new Object[]{ true,  HasFields.class, "bogus_sL", Object.class }, Error.class });
 627             CASES = cases.toArray(new Object[0][]);
























































 628         }
 629     }
 630 
 631     static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10, TEST_BOUND = 0x20, TEST_NPE = 0x40;
 632 
 633     static boolean testModeMatches(int testMode, boolean isStatic) {
 634         switch (testMode) {
 635         case TEST_FIND_STATIC:          return isStatic;
 636         case TEST_FIND_FIELD:           return !isStatic;
 637         case TEST_UNREFLECT:            return true;  // unreflect matches both
 638         }
 639         throw new InternalError("testMode="+testMode);
 640     }
 641 
 642     static class Callee {
 643         static Object id() { return called("id"); }
 644         static Object id(Object x) { return called("id", x); }
 645         static Object id(Object x, Object y) { return called("id", x, y); }
 646         static Object id(Object x, Object y, Object z) { return called("id", x, y, z); }
 647         static Object id(Object... vx) { return called("id", vx); }


< prev index next >