aboutsummaryrefslogtreecommitdiff
path: root/src/utils/lombok
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
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')
-rw-r--r--src/utils/lombok/core/FieldAugment.java5
-rw-r--r--src/utils/lombok/javac/CommentCatcher.java5
-rw-r--r--src/utils/lombok/javac/Javac.java20
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java21
-rw-r--r--src/utils/lombok/javac/PackageName.java4
-rw-r--r--src/utils/lombok/javac/java6/CommentCollectingParserFactory.java5
-rw-r--r--src/utils/lombok/javac/java7/CommentCollectingParserFactory.java5
-rw-r--r--src/utils/lombok/javac/java8/CommentCollectingParserFactory.java5
-rw-r--r--src/utils/lombok/javac/java9/CommentCollectingParserFactory.java5
-rw-r--r--src/utils/lombok/permit/Permit.java100
-rw-r--r--src/utils/lombok/permit/package-info.java8
11 files changed, 149 insertions, 34 deletions
diff --git a/src/utils/lombok/core/FieldAugment.java b/src/utils/lombok/core/FieldAugment.java
index ee8acf4d..4a32ad04 100644
--- a/src/utils/lombok/core/FieldAugment.java
+++ b/src/utils/lombok/core/FieldAugment.java
@@ -27,6 +27,8 @@ import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.WeakHashMap;
+import lombok.permit.Permit;
+
public abstract class FieldAugment<T, F> {
private static Object getDefaultValue(Class<?> type) {
if (type == boolean.class) return false;
@@ -101,10 +103,9 @@ public abstract class FieldAugment<T, F> {
private static Field findField(Class<?> type, Class<?> wantedType, String name) {
try {
- Field f = type.getDeclaredField(name);
+ Field f = Permit.getField(type, name);
if (Modifier.isStatic(f.getModifiers()) || Modifier.isFinal(f.getModifiers())) return null;
if (!typeIsAssignmentCompatible(f.getType(), wantedType)) return null;
- f.setAccessible(true);
return f;
} catch (Exception e) {
return null;
diff --git a/src/utils/lombok/javac/CommentCatcher.java b/src/utils/lombok/javac/CommentCatcher.java
index afbd7b52..f8b73b0a 100644
--- a/src/utils/lombok/javac/CommentCatcher.java
+++ b/src/utils/lombok/javac/CommentCatcher.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.List;
import lombok.core.FieldAugment;
+import lombok.permit.Permit;
import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -79,7 +80,7 @@ public class CommentCatcher {
} else {
scannerFactory = Class.forName("lombok.javac.java8.CommentCollectingScannerFactory");
}
- scannerFactory.getMethod("preRegister", Context.class).invoke(null, context);
+ Permit.getMethod(scannerFactory, "preRegister", Context.class).invoke(null, context);
} catch (InvocationTargetException e) {
throw Javac.sneakyThrow(e.getCause());
} catch (Exception e) {
@@ -100,7 +101,7 @@ public class CommentCatcher {
} else {
parserFactory = Class.forName("lombok.javac.java9.CommentCollectingParserFactory");
}
- parserFactory.getMethod("setInCompiler", JavaCompiler.class, Context.class).invoke(null, compiler, context);
+ Permit.getMethod(parserFactory, "setInCompiler", JavaCompiler.class, Context.class).invoke(null, compiler, context);
} catch (InvocationTargetException e) {
throw Javac.sneakyThrow(e.getCause());
} catch (Exception e) {
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index 92961726..a2cb32c6 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -40,6 +40,7 @@ import lombok.core.ClassLiteral;
import lombok.core.FieldSelect;
import lombok.javac.JavacTreeMaker.TreeTag;
import lombok.javac.JavacTreeMaker.TypeTag;
+import lombok.permit.Permit;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symtab;
@@ -199,7 +200,6 @@ public class Javac {
static {
getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class<?>[0]);
- getExtendsClause.setAccessible(true);
if (getJavaCompilerVersion() < 8) {
getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", java.util.Map.class);
@@ -214,11 +214,11 @@ public class Javac {
throw sneakyThrow(ex);
}
try {
- storeEndMethodTemp = endPosTable.getMethod("storeEnd", JCTree.class, int.class);
+ storeEndMethodTemp = Permit.getMethod(endPosTable, "storeEnd", JCTree.class, int.class);
} catch (NoSuchMethodException e) {
try {
endPosTable = Class.forName("com.sun.tools.javac.parser.JavacParser$AbstractEndPosTable");
- storeEndMethodTemp = endPosTable.getDeclaredMethod("storeEnd", JCTree.class, int.class);
+ storeEndMethodTemp = Permit.getMethod(endPosTable, "storeEnd", JCTree.class, int.class);
} catch (NoSuchMethodException ex) {
throw sneakyThrow(ex);
} catch (ClassNotFoundException ex) {
@@ -227,13 +227,13 @@ public class Javac {
}
storeEnd = storeEndMethodTemp;
}
- getEndPosition.setAccessible(true);
- storeEnd.setAccessible(true);
+ Permit.setAccessible(getEndPosition);
+ Permit.setAccessible(storeEnd);
}
private static Method getMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
try {
- return clazz.getMethod(name, paramTypes);
+ return Permit.getMethod(clazz, name, paramTypes);
} catch (NoSuchMethodException e) {
throw sneakyThrow(e);
}
@@ -243,7 +243,7 @@ public class Javac {
try {
Class<?>[] c = new Class[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) c[i] = Class.forName(paramTypes[i]);
- return clazz.getMethod(name, c);
+ return Permit.getMethod(clazz, name, c);
} catch (NoSuchMethodException e) {
throw sneakyThrow(e);
} catch (ClassNotFoundException e) {
@@ -320,7 +320,7 @@ public class Javac {
private static Field getFieldIfExists(Class<?> c, String fieldName) {
try {
- return c.getField("voidType");
+ return Permit.getField(c, "voidType");
} catch (Exception e) {
return null;
}
@@ -370,13 +370,13 @@ public class Javac {
static {
Field f = null;
try {
- f = JCCompilationUnit.class.getDeclaredField("endPositions");
+ f = Permit.getField(JCCompilationUnit.class, "endPositions");
} catch (NoSuchFieldException e) {}
JCCOMPILATIONUNIT_ENDPOSITIONS = f;
f = null;
try {
- f = JCCompilationUnit.class.getDeclaredField("docComments");
+ f = Permit.getField(JCCompilationUnit.class, "docComments");
} catch (NoSuchFieldException e) {}
JCCOMPILATIONUNIT_DOCCOMMENTS = f;
}
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
index 5f4fb09c..68a16af2 100644
--- a/src/utils/lombok/javac/JavacTreeMaker.java
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -88,6 +88,8 @@ import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
+import lombok.permit.Permit;
+
public class JavacTreeMaker {
private final TreeMaker tm;
@@ -153,7 +155,7 @@ public class JavacTreeMaker {
Object value = cache.get(fieldName);
if (value != null) return value;
try {
- value = Class.forName(className).getField(fieldName).get(null);
+ value = Permit.getField(Class.forName(className), fieldName).get(null);
} catch (NoSuchFieldException e) {
throw Javac.sneakyThrow(e);
} catch (IllegalAccessException e) {
@@ -169,7 +171,7 @@ public class JavacTreeMaker {
private static Field NOSUCHFIELDEX_MARKER;
static {
try {
- NOSUCHFIELDEX_MARKER = SchroedingerType.class.getDeclaredField("NOSUCHFIELDEX_MARKER");
+ NOSUCHFIELDEX_MARKER = Permit.getField(SchroedingerType.class, "NOSUCHFIELDEX_MARKER");
} catch (NoSuchFieldException e) {
throw Javac.sneakyThrow(e);
}
@@ -180,12 +182,12 @@ public class JavacTreeMaker {
Field field = cache.get(c);
if (field == null) {
try {
- field = c.getField(fieldName);
+ field = Permit.getField(c, fieldName);
} catch (NoSuchFieldException e) {
cache.putIfAbsent(c, NOSUCHFIELDEX_MARKER);
throw Javac.sneakyThrow(e);
}
- field.setAccessible(true);
+ Permit.setAccessible(field);
Field old = cache.putIfAbsent(c, field);
if (old != null) field = old;
}
@@ -207,8 +209,7 @@ public class JavacTreeMaker {
static {
Method m = null;
try {
- m = Type.class.getDeclaredMethod("getTag");
- m.setAccessible(true);
+ m = Permit.getMethod(Type.class, "getTag");
} catch (NoSuchMethodException e) {}
TYPE_TYPETAG_METHOD = m;
}
@@ -255,8 +256,7 @@ public class JavacTreeMaker {
static {
Method m = null;
try {
- m = JCTree.class.getDeclaredMethod("getTag");
- m.setAccessible(true);
+ m = Permit.getMethod(JCTree.class, "getTag");
} catch (NoSuchMethodException e) {}
if (m != null) {
@@ -265,8 +265,7 @@ public class JavacTreeMaker {
} else {
Field f = null;
try {
- f = JCTree.class.getDeclaredField("tag");
- f.setAccessible(true);
+ f = Permit.getField(JCTree.class, "tag");
} catch (NoSuchFieldException e) {}
TAG_FIELD = f;
TAG_METHOD = null;
@@ -381,7 +380,7 @@ public class JavacTreeMaker {
else throw new IllegalStateException("Lombok TreeMaker frontend issue: multiple matches when looking for method: " + m);
}
if (found == null) throw new IllegalStateException("Lombok TreeMaker frontend issue: no match when looking for method: " + m);
- found.setAccessible(true);
+ Permit.setAccessible(found);
Object marker = METHOD_CACHE.putIfAbsent(m, found);
if (marker == null) return found;
return METHOD_CACHE.get(m);
diff --git a/src/utils/lombok/javac/PackageName.java b/src/utils/lombok/javac/PackageName.java
index e4dd6b20..72892cca 100644
--- a/src/utils/lombok/javac/PackageName.java
+++ b/src/utils/lombok/javac/PackageName.java
@@ -28,13 +28,15 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
+import lombok.permit.Permit;
+
// Supports JDK6-9
public class PackageName {
private static final Method packageNameMethod = getPackageNameMethod();
private static Method getPackageNameMethod() {
try {
- return JCCompilationUnit.class.getDeclaredMethod("getPackageName");
+ return Permit.getMethod(JCCompilationUnit.class, "getPackageName");
} catch (Exception e) {
return null;
}
diff --git a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
index 0cf8fdcd..5d96f9d1 100644
--- a/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java6/CommentCollectingParserFactory.java
@@ -28,6 +28,8 @@ import com.sun.tools.javac.parser.Lexer;
import com.sun.tools.javac.parser.Parser;
import com.sun.tools.javac.util.Context;
+import lombok.permit.Permit;
+
public class CommentCollectingParserFactory extends Parser.Factory {
static Context.Key<Parser.Factory> key() {
return parserFactoryKey;
@@ -49,8 +51,7 @@ public class CommentCollectingParserFactory extends Parser.Factory {
context.put(CommentCollectingParserFactory.key(), (Parser.Factory)null);
Field field;
try {
- field = JavaCompiler.class.getDeclaredField("parserFactory");
- field.setAccessible(true);
+ field = Permit.getField(JavaCompiler.class, "parserFactory");
field.set(compiler, new CommentCollectingParserFactory(context));
} catch (Exception e) {
throw new IllegalStateException("Could not set comment sensitive parser in the compiler", e);
diff --git a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
index ffd68f55..7ef937cd 100644
--- a/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java7/CommentCollectingParserFactory.java
@@ -30,6 +30,8 @@ import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.util.Context;
+import lombok.permit.Permit;
+
public class CommentCollectingParserFactory extends ParserFactory {
private final Context context;
@@ -56,8 +58,7 @@ public class CommentCollectingParserFactory extends ParserFactory {
context.put(CommentCollectingParserFactory.key(), (ParserFactory)null);
Field field;
try {
- field = JavaCompiler.class.getDeclaredField("parserFactory");
- field.setAccessible(true);
+ field = Permit.getField(JavaCompiler.class, "parserFactory");
field.set(compiler, new CommentCollectingParserFactory(context));
} catch (Exception e) {
throw new IllegalStateException("Could not set comment sensitive parser in the compiler", e);
diff --git a/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
index 2fdaddfe..0988ce6d 100644
--- a/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java8/CommentCollectingParserFactory.java
@@ -30,6 +30,8 @@ import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.util.Context;
+import lombok.permit.Permit;
+
public class CommentCollectingParserFactory extends ParserFactory {
private final Context context;
@@ -66,8 +68,7 @@ public class CommentCollectingParserFactory extends ParserFactory {
context.put(CommentCollectingParserFactory.key(), (ParserFactory) null);
Field field;
try {
- field = JavaCompiler.class.getDeclaredField("parserFactory");
- field.setAccessible(true);
+ field = Permit.getField(JavaCompiler.class, "parserFactory");
field.set(compiler, new CommentCollectingParserFactory(context));
} catch (Exception e) {
throw new IllegalStateException("Could not set comment sensitive parser in the compiler", e);
diff --git a/src/utils/lombok/javac/java9/CommentCollectingParserFactory.java b/src/utils/lombok/javac/java9/CommentCollectingParserFactory.java
index 5af4a419..208d2570 100644
--- a/src/utils/lombok/javac/java9/CommentCollectingParserFactory.java
+++ b/src/utils/lombok/javac/java9/CommentCollectingParserFactory.java
@@ -30,6 +30,8 @@ import com.sun.tools.javac.parser.ParserFactory;
import com.sun.tools.javac.parser.ScannerFactory;
import com.sun.tools.javac.util.Context;
+import lombok.permit.Permit;
+
public class CommentCollectingParserFactory extends ParserFactory {
private final Context context;
@@ -60,8 +62,7 @@ public class CommentCollectingParserFactory extends ParserFactory {
context.put(CommentCollectingParserFactory.key(), (ParserFactory) null);
Field field;
try {
- field = JavaCompiler.class.getDeclaredField("parserFactory");
- field.setAccessible(true);
+ field = Permit.getField(JavaCompiler.class, "parserFactory");
field.set(compiler, new CommentCollectingParserFactory(context));
} catch (Exception e) {
throw new IllegalStateException("Could not set comment sensitive parser in the compiler", e);
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;
+ }
+ }
+}
diff --git a/src/utils/lombok/permit/package-info.java b/src/utils/lombok/permit/package-info.java
new file mode 100644
index 00000000..a28f7160
--- /dev/null
+++ b/src/utils/lombok/permit/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * This is a reduced copy of the nqzero Permit-reflect project.
+ * https://github.com/nqzero/permit-reflect
+ *
+ * Many thanks to nqzero. The permit-reflect project is, like lombok itself, licensed under the MIT license.
+ * See https://github.com/nqzero/permit-reflect/blob/master/License for license info.
+ */
+package lombok.permit; \ No newline at end of file