aboutsummaryrefslogtreecommitdiff
path: root/src/utils/lombok/permit/Permit.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2018-10-29 23:13:52 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2018-10-29 23:13:59 +0100
commiteca219ee6433cd964f0549a114a791ca4eb9f0fa (patch)
tree20f6fed449504fbf5dbc52bd15ff3f2458dd90f8 /src/utils/lombok/permit/Permit.java
parent182cb0cb9e8db6341fb4633c3849b5e90ba6d088 (diff)
downloadlombok-eca219ee6433cd964f0549a114a791ca4eb9f0fa.tar.gz
lombok-eca219ee6433cd964f0549a114a791ca4eb9f0fa.tar.bz2
lombok-eca219ee6433cd964f0549a114a791ca4eb9f0fa.zip
eliminate ‘you are using private API’ warnings by streamlining all reflective access via a class that uses sun.misc.Unsafe to arrange access. From the nqzero permit-reflect library.
Diffstat (limited to 'src/utils/lombok/permit/Permit.java')
-rw-r--r--src/utils/lombok/permit/Permit.java100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java
new file mode 100644
index 00000000..00b8274c
--- /dev/null
+++ b/src/utils/lombok/permit/Permit.java
@@ -0,0 +1,100 @@
+package lombok.permit;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.util.List;
+
+// sunapi suppresses javac's warning about using Unsafe; 'all' suppresses eclipse's warning about the unspecified 'sunapi' key. Leave them both.
+// Yes, javac's definition of the word 'all' is quite contrary to what the dictionary says it means. 'all' does NOT include 'sunapi' according to javac.
+@SuppressWarnings({"sunapi", "all"})
+public class Permit {
+ private Permit() {}
+
+
+ private static final long ACCESSIBLE_OVERRIDE_FIELD_OFFSET;
+ private static final IllegalAccessException INIT_ERROR;
+ private static final sun.misc.Unsafe UNSAFE = (sun.misc.Unsafe) reflectiveStaticFieldAccess(sun.misc.Unsafe.class, "theUnsafe");
+
+ static {
+ Field f;
+ long g;
+ Throwable ex;
+
+ try {
+ f = AccessibleObject.class.getDeclaredField("override");
+ g = UNSAFE.objectFieldOffset(f);
+ ex = null;
+ } catch (Throwable t) {
+ f = null;
+ g = -1L;
+ ex = t;
+ }
+
+ ACCESSIBLE_OVERRIDE_FIELD_OFFSET = g;
+ if (ex == null) INIT_ERROR = null;
+ else if (ex instanceof IllegalAccessException) INIT_ERROR = (IllegalAccessException) ex;
+ else {
+ INIT_ERROR = new IllegalAccessException("Cannot initialize Unsafe-based permit");
+ INIT_ERROR.initCause(ex);
+ }
+ }
+
+ public static <T extends AccessibleObject> T setAccessible(T accessor) {
+ if (INIT_ERROR == null) {
+ UNSAFE.putBoolean(accessor, ACCESSIBLE_OVERRIDE_FIELD_OFFSET, true);
+ } else {
+ accessor.setAccessible(true);
+ }
+
+ return accessor;
+ }
+
+ public static Method getMethod(Class<?> c, String mName, Class<?>... parameterTypes) throws NoSuchMethodException {
+ Method m = null;
+ Class<?> oc = c;
+ while (c != null) {
+ try {
+ m = c.getDeclaredMethod(mName, parameterTypes);
+ break;
+ } catch (NoSuchMethodException e) {}
+ c = c.getSuperclass();
+ }
+
+ if (m == null) throw new NoSuchMethodException(oc.getName() + " :: " + mName + "(args)");
+ return setAccessible(m);
+ }
+
+ public static Field getField(Class<?> c, String fName) throws NoSuchFieldException {
+ Field f = null;
+ Class<?> oc = c;
+ while (c != null) {
+ try {
+ f = c.getDeclaredField(fName);
+ break;
+ } catch (NoSuchFieldException e) {}
+ c = c.getSuperclass();
+ }
+
+ if (f == null) throw new NoSuchFieldException(oc.getName() + " :: " + fName);
+
+ return setAccessible(f);
+ }
+
+ public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... parameterTypes) throws NoSuchMethodException {
+ return setAccessible(c.getDeclaredConstructor(parameterTypes));
+ }
+
+ private static Object reflectiveStaticFieldAccess(Class<?> c, String fName) {
+ try {
+ Field f = c.getDeclaredField(fName);
+ f.setAccessible(true);
+ return f.get(null);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}