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.

This commit is contained in:
Reinier Zwitserloot committed 2018-10-29 23:13:59 +01:00
1 parent 182cb0cb9e
commit eca219ee64
32 files changed
+276 -188

No files matched your search

+2 -1
View File
@@ -39,6 +39,7 @@ import java.util.concurrent.ConcurrentMap;
import lombok.core.configuration.ConfigurationKey;
import lombok.core.debug.HistogramTracker;
import lombok.permit.Permit;
/**
* Lombok wraps the AST produced by a target platform into its own AST system, mostly because both Eclipse and javac
@@ -252,7 +253,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
}
if (shouldDrill(c, t, f.getName())) {
f.setAccessible(true);
Permit.setAccessible(f);
fields.add(new FieldAccess(f, dim));
}
}
@@ -46,6 +46,7 @@ import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import lombok.patcher.ClassRootFinder;
import lombok.permit.Permit;
@SupportedAnnotationTypes("*")
public class AnnotationProcessor extends AbstractProcessor {
@@ -82,8 +83,7 @@ public class AnnotationProcessor extends AbstractProcessor {
for (Class<?> procEnvClass = procEnv.getClass(); procEnvClass != null; procEnvClass = procEnvClass.getSuperclass()) {
try {
Field field = procEnvClass.getDeclaredField("delegate");
field.setAccessible(true);
Field field = Permit.getField(procEnvClass, "delegate");
Object delegate = field.get(procEnv);
return tryRecursivelyObtainJavacProcessingEnvironment((ProcessingEnvironment) delegate);
@@ -136,7 +136,7 @@ public class AnnotationProcessor extends AbstractProcessor {
ClassLoader environmentClassLoader = procEnv.getClass().getClassLoader();
if (environmentClassLoader != null && environmentClassLoader.getClass().getCanonicalName().equals("org.codehaus.plexus.compiler.javac.IsolatedClassLoader")) {
if (!ClassLoader_lombokAlreadyAddedTo.getAndSet(environmentClassLoader, true)) {
Method m = environmentClassLoader.getClass().getDeclaredMethod("addURL", URL.class);
Method m = Permit.getMethod(environmentClassLoader.getClass(), "addURL", URL.class);
URL selfUrl = new File(ClassRootFinder.findClassRootOfClass(AnnotationProcessor.class)).toURI().toURL();
m.invoke(environmentClassLoader, selfUrl);
}
+2 -1
View File
@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Map;
import lombok.core.AST.Kind;
import lombok.permit.Permit;
/**
* Represents a single annotation in a source file and can be used to query the parameters present on it.
@@ -210,7 +211,7 @@ public class AnnotationValues<A extends Annotation> {
public <T> T getDefaultIf(String methodName, Class<T> type, T defaultValue) {
try {
return type.cast(type.getMethod(methodName).getDefaultValue());
return type.cast(Permit.getMethod(type, methodName).getDefaultValue());
} catch (Exception e) {
return defaultValue;
}
+2 -1
View File
@@ -34,6 +34,7 @@ import lombok.Lombok;
import lombok.core.AST;
import lombok.core.LombokImmutableList;
import lombok.eclipse.handlers.EclipseHandlerUtil;
import lombok.permit.Permit;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
@@ -497,7 +498,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
Throwable problem_ = null;
Method m = null;
try {
m = EclipseAstProblemView.class.getMethod("addProblemToCompilationResult", char[].class, Class.forName(COMPILATIONRESULT_TYPE), boolean.class, String.class, int.class, int.class);
m = Permit.getMethod(EclipseAstProblemView.class, "addProblemToCompilationResult", char[].class, Class.forName(COMPILATIONRESULT_TYPE), boolean.class, String.class, int.class, int.class);
} catch (Throwable t) {
// That's problematic, but as long as no local classes are used we don't actually need it.
// Better fail on local classes than crash altogether.
@@ -30,6 +30,7 @@ import lombok.core.LombokConfiguration;
import lombok.core.debug.DebugSnapshotStore;
import lombok.core.debug.HistogramTracker;
import lombok.patcher.Symbols;
import lombok.permit.Permit;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -90,7 +91,7 @@ public class TransformEclipseAST {
disableLombok = true;
}
try {
f = CompilationUnitDeclaration.class.getDeclaredField("$lombokAST");
f = Permit.getField(CompilationUnitDeclaration.class, "$lombokAST");
} catch (Throwable t) {
//I guess we're in an ecj environment; we'll just not cache stuff then.
}
@@ -56,6 +56,7 @@ import lombok.eclipse.EclipseAST;
import lombok.eclipse.EclipseNode;
import lombok.experimental.Accessors;
import lombok.experimental.Tolerate;
import lombok.permit.Permit;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -337,9 +338,7 @@ public class EclipseHandlerUtil {
private static Field getField(Class<?> c, String fName) {
try {
Field f = c.getDeclaredField(fName);
f.setAccessible(true);
return f;
return Permit.getField(c, fName);
} catch (Exception e) {
return null;
}
@@ -1931,12 +1930,12 @@ public class EclipseHandlerUtil {
Constructor<IntLiteral> intLiteralConstructor_ = null;
Method intLiteralFactoryMethod_ = null;
try {
intLiteralConstructor_ = IntLiteral.class.getConstructor(parameterTypes);
intLiteralConstructor_ = Permit.getConstructor(IntLiteral.class, parameterTypes);
} catch (Throwable ignore) {
// probably eclipse 3.7++
}
try {
intLiteralFactoryMethod_ = IntLiteral.class.getMethod("buildIntLiteral", parameterTypes);
intLiteralFactoryMethod_ = Permit.getMethod(IntLiteral.class, "buildIntLiteral", parameterTypes);
} catch (Throwable ignore) {
// probably eclipse versions before 3.7
}
@@ -39,6 +39,8 @@ import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import lombok.permit.Permit;
/**
* During resolution, the resolver will emit resolution errors, but without appropriate file names and line numbers. If these resolution errors stick around
* then they will be generated AGAIN, this time with proper names and line numbers, at the end. Therefore, we want to suppress the logger.
@@ -89,11 +91,8 @@ public final class CompilerMessageSuppressor {
static Field getDeclaredField(Class<?> c, String fieldName) {
try {
Field field = c.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}
catch (Throwable t) {
return Permit.getField(c, fieldName);
} catch (Throwable t) {
return null;
}
}
@@ -25,6 +25,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import lombok.Lombok;
import lombok.permit.Permit;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Options;
@@ -36,8 +37,8 @@ public class Javac6BasedLombokOptions extends LombokOptions {
static {
try {
Class<?> optionNameClass = Class.forName("com.sun.tools.javac.main.OptionName");
optionName_valueOf = optionNameClass.getMethod("valueOf", String.class);
options_put = Class.forName("com.sun.tools.javac.util.Options").getMethod("put", optionNameClass, String.class);
optionName_valueOf = Permit.getMethod(optionNameClass, "valueOf", String.class);
options_put = Permit.getMethod(Class.forName("com.sun.tools.javac.util.Options"), "put", optionNameClass, String.class);
} catch (Exception e) {
throw new IllegalArgumentException("Can't initialize Javac6-based lombok options due to reflection issue.", e);
}
+24 -28
View File
@@ -37,6 +37,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.util.JCDiagnostic;
import lombok.core.AST;
import lombok.permit.Permit;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symtab;
@@ -243,7 +244,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
private static List<JCTree> getResourcesForTryNode(JCTry tryNode) {
if (!JCTRY_RESOURCES_FIELD_INITIALIZED) {
try {
JCTRY_RESOURCES_FIELD = JCTry.class.getField("resources");
JCTRY_RESOURCES_FIELD = Permit.getField(JCTry.class, "resources");
} catch (NoSuchFieldException ignore) {
// Java 1.6 or lower won't have this at all.
} catch (Exception ignore) {
@@ -343,7 +344,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
return m;
}
try {
m = c.getMethod("getBody");
m = Permit.getMethod(c, "getBody");
} catch (NoSuchMethodException e) {
throw Javac.sneakyThrow(e);
}
@@ -501,12 +502,11 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
}
static ErrorLog create(Messager messager, Log log) {
Field errorCount = null;
try {
Field f = messager.getClass().getDeclaredField("errorCount");
f.setAccessible(true);
errorCount = f;
} catch (Throwable t) {}
Field errorCount; try {
errorCount = Permit.getField(messager.getClass(), "errorCount");
} catch (Throwable t) {
errorCount = null;
}
boolean hasMultipleErrors = false;
for (Field field : log.getClass().getFields()) {
if (field.getName().equals("multipleErrors")) {
@@ -515,14 +515,13 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
}
}
if (hasMultipleErrors) return new JdkBefore9(log, messager, errorCount);
Field warningCount = null;
try {
Field f = messager.getClass().getDeclaredField("warningCount");
f.setAccessible(true);
warningCount = f;
} catch (Throwable t) {}
Field warningCount; try {
warningCount = Permit.getField(messager.getClass(), "warningCount");
} catch (Throwable t) {
warningCount = null;
}
return new Jdk9Plus(log, messager, errorCount, warningCount);
}
}
@@ -577,21 +576,18 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> {
Class<?> noteCls = Class.forName(jcd + "$Note");
Class<?> lc = log.getClass();
this.errorMethod = lc.getMethod("error", df, DiagnosticPosition.class, errorCls);
this.warningMethod = lc.getMethod("warning", DiagnosticPosition.class, warningCls);
this.mandatoryWarningMethod = lc.getMethod("mandatoryWarning", DiagnosticPosition.class, warningCls);
this.noteMethod = lc.getMethod("note", DiagnosticPosition.class, noteCls);
this.errorMethod = Permit.getMethod(lc, "error", df, DiagnosticPosition.class, errorCls);
this.warningMethod = Permit.getMethod(lc, "warning", DiagnosticPosition.class, warningCls);
this.mandatoryWarningMethod = Permit.getMethod(lc, "mandatoryWarning", DiagnosticPosition.class, warningCls);
this.noteMethod = Permit.getMethod(lc, "note", DiagnosticPosition.class, noteCls);
Field diagsField = lc.getSuperclass().getDeclaredField("diags");
diagsField.setAccessible(true);
this.diags = (JCDiagnostic.Factory)diagsField.get(log);
Field diagsField = Permit.getField(lc.getSuperclass(), "diags");
this.diags = (JCDiagnostic.Factory) diagsField.get(log);
Class<?> dc = this.diags.getClass();
this.errorKey = dc.getMethod("errorKey", String.class, Object[].class);
this.warningKey = dc.getDeclaredMethod("warningKey", String.class, Object[].class);
this.warningKey.setAccessible(true);
this.noteKey = dc.getDeclaredMethod("noteKey", String.class, Object[].class);
this.noteKey.setAccessible(true);
this.errorKey = Permit.getMethod(dc, "errorKey", String.class, Object[].class);
this.warningKey = Permit.getMethod(dc, "warningKey", String.class, Object[].class);
this.noteKey = Permit.getMethod(dc, "noteKey", String.class, Object[].class);
} catch (Throwable t) {
//t.printStackTrace();
}
+4 -7
View File
@@ -35,6 +35,7 @@ import javax.tools.JavaFileObject;
import lombok.Lombok;
import lombok.core.debug.AssertionLogger;
import lombok.permit.Permit;
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
@@ -162,14 +163,10 @@ public class JavacResolution {
private static Field getMemberEnterDotEnv() {
if (memberEnterDotEnv != null) return memberEnterDotEnv;
try {
Field f = MemberEnter.class.getDeclaredField("env");
f.setAccessible(true);
memberEnterDotEnv = f;
return memberEnterDotEnv = Permit.getField(MemberEnter.class, "env");
} catch (NoSuchFieldException e) {
return null;
}
return memberEnterDotEnv;
}
@SuppressWarnings("unchecked")
@@ -252,10 +249,10 @@ public class JavacResolution {
static {
Method upperBound = null;
try {
upperBound = Types.class.getMethod("upperBound", Type.class);
upperBound = Permit.getMethod(Types.class, "upperBound", Type.class);
} catch (Throwable ignore) {}
if (upperBound == null) try {
upperBound = Types.class.getMethod("wildUpperBound", Type.class);
upperBound = Permit.getMethod(Types.class, "wildUpperBound", Type.class);
} catch (Throwable ignore) {}
UPPER_BOUND = upperBound;
@@ -39,6 +39,7 @@ import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import lombok.core.DiagnosticsReceiver;
import lombok.permit.Permit;
import com.sun.tools.javac.file.BaseFileManager;
@@ -87,16 +88,14 @@ final class LombokFileObjects {
}
static Method getDecoderMethod(String className) {
Method m = null;
try {
m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class);
m.setAccessible(true);
return Permit.getMethod(Class.forName(className), "getDecoder", boolean.class);
} catch (NoSuchMethodException e) {
// Intentional fallthrough - getDecoder(boolean) is not always present.
} catch (ClassNotFoundException e) {
// Intentional fallthrough - getDecoder(boolean) is not always present.
}
return m;
return null;
}
private LombokFileObjects() {}
+25 -43
View File
@@ -52,6 +52,7 @@ import javax.tools.JavaFileObject;
import lombok.Lombok;
import lombok.core.DiagnosticsReceiver;
import lombok.javac.JavacTransformer;
import lombok.permit.Permit;
import com.sun.source.util.TreePath;
import com.sun.source.util.Trees;
@@ -112,10 +113,7 @@ public class LombokProcessor extends AbstractProcessor {
private static final Field getFieldAccessor(String typeName, String fieldName) {
try {
Class<?> c = Class.forName(typeName);
Field f = c.getDeclaredField(fieldName);
f.setAccessible(true);
return f;
return Permit.getField(Class.forName(typeName), fieldName);
} catch (ClassNotFoundException e) {
return null;
} catch (NoSuchFieldException e) {
@@ -156,11 +154,9 @@ public class LombokProcessor extends AbstractProcessor {
Context context = javacProcessingEnv.getContext();
disablePartialReparseInNetBeansEditor(context);
try {
Method keyMethod = Context.class.getDeclaredMethod("key", Class.class);
keyMethod.setAccessible(true);
Method keyMethod = Permit.getMethod(Context.class, "key", Class.class);
Object key = keyMethod.invoke(context, JavaFileManager.class);
Field htField = Context.class.getDeclaredField("ht");
htField.setAccessible(true);
Field htField = Permit.getField(Context.class, "ht");
@SuppressWarnings("unchecked")
Map<Object,Object> ht = (Map<Object,Object>) htField.get(context);
final JavaFileManager originalFiler = (JavaFileManager) ht.get(key);
@@ -170,8 +166,7 @@ public class LombokProcessor extends AbstractProcessor {
JavaFileManager newFilerManager = new InterceptingJavaFileManager(originalFiler, receiver);
ht.put(key, newFilerManager);
Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager");
filerFileManagerField.setAccessible(true);
Field filerFileManagerField = Permit.getField(JavacFiler.class, "fileManager");
filerFileManagerField.set(javacFiler, newFilerManager);
if (lombok.javac.Javac.getJavaCompilerVersion() > 8
@@ -186,20 +181,17 @@ public class LombokProcessor extends AbstractProcessor {
private void replaceFileManagerJdk9(Context context, JavaFileManager newFiler) {
try {
JavaCompiler compiler = (JavaCompiler) JavaCompiler.class.getDeclaredMethod("instance", Context.class).invoke(null, context);
JavaCompiler compiler = (JavaCompiler) Permit.getMethod(JavaCompiler.class, "instance", Context.class).invoke(null, context);
try {
Field fileManagerField = JavaCompiler.class.getDeclaredField("fileManager");
fileManagerField.setAccessible(true);
Field fileManagerField = Permit.getField(JavaCompiler.class, "fileManager");
fileManagerField.set(compiler, newFiler);
}
catch (Exception e) {}
try {
Field writerField = JavaCompiler.class.getDeclaredField("writer");
writerField.setAccessible(true);
Field writerField = Permit.getField(JavaCompiler.class, "writer");
ClassWriter writer = (ClassWriter) writerField.get(compiler);
Field fileManagerField = ClassWriter.class.getDeclaredField("fileManager");
fileManagerField.setAccessible(true);
Field fileManagerField = Permit.getField(ClassWriter.class, "fileManager");
fileManagerField.set(writer, newFiler);
}
catch (Exception e) {}
@@ -210,8 +202,7 @@ public class LombokProcessor extends AbstractProcessor {
private void forceMultipleRoundsInNetBeansEditor() {
try {
Field f = JavacProcessingEnvironment.class.getDeclaredField("isBackgroundCompilation");
f.setAccessible(true);
Field f = Permit.getField(JavacProcessingEnvironment.class, "isBackgroundCompilation");
f.set(javacProcessingEnv, true);
} catch (NoSuchFieldException e) {
// only NetBeans has it
@@ -223,14 +214,12 @@ public class LombokProcessor extends AbstractProcessor {
private void disablePartialReparseInNetBeansEditor(Context context) {
try {
Class<?> cancelServiceClass = Class.forName("com.sun.tools.javac.util.CancelService");
Method cancelServiceInstace = cancelServiceClass.getDeclaredMethod("instance", Context.class);
Method cancelServiceInstace = Permit.getMethod(cancelServiceClass, "instance", Context.class);
Object cancelService = cancelServiceInstace.invoke(null, context);
if (cancelService == null) return;
Field parserField = cancelService.getClass().getDeclaredField("parser");
parserField.setAccessible(true);
Field parserField = Permit.getField(cancelService.getClass(), "parser");
Object parser = parserField.get(cancelService);
Field supportsReparseField = parser.getClass().getDeclaredField("supportsReparse");
supportsReparseField.setAccessible(true);
Field supportsReparseField = Permit.getField(parser.getClass(), "supportsReparse");
supportsReparseField.set(parser, false);
} catch (ClassNotFoundException e) {
// only NetBeans has it
@@ -284,8 +273,7 @@ public class LombokProcessor extends AbstractProcessor {
private void stopJavacProcessingEnvironmentFromClosingOurClassloader() {
try {
Field f = JavacProcessingEnvironment.class.getDeclaredField("processorClassLoader");
f.setAccessible(true);
Field f = Permit.getField(JavacProcessingEnvironment.class, "processorClassLoader");
ClassLoader unwrapped = (ClassLoader) f.get(javacProcessingEnv);
if (unwrapped == null) return;
ClassLoader wrapped = wrapClassLoader(unwrapped);
@@ -377,7 +365,7 @@ public class LombokProcessor extends AbstractProcessor {
} catch (Exception e) {
e.printStackTrace();
processingEnv.getMessager().printMessage(Kind.WARNING,
"Can't force a new processing round. Lombok won't work.");
"Can't force a new processing round. Lombok won't work.");
}
}
}
@@ -414,16 +402,14 @@ public class LombokProcessor extends AbstractProcessor {
@Override public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
/**
* This class casts the given processing environment to a JavacProcessingEnvironment. In case of
* gradle incremental compilation, the delegate ProcessingEnvironment of the gradle wrapper is returned.
*/
public JavacProcessingEnvironment getJavacProcessingEnvironment(Object procEnv) {
if (procEnv instanceof JavacProcessingEnvironment) {
return (JavacProcessingEnvironment) procEnv;
}
if (procEnv instanceof JavacProcessingEnvironment) return (JavacProcessingEnvironment) procEnv;
// try to find a "delegate" field in the object, and use this to try to obtain a JavacProcessingEnvironment
for (Class<?> procEnvClass = procEnv.getClass(); procEnvClass != null; procEnvClass = procEnvClass.getSuperclass()) {
try {
@@ -432,9 +418,9 @@ public class LombokProcessor extends AbstractProcessor {
// delegate field was not found, try on superclass
}
}
processingEnv.getMessager().printMessage(Kind.WARNING,
"Can't get the delegate of the gradle IncrementalProcessingEnvironment. Lombok won't work.");
"Can't get the delegate of the gradle IncrementalProcessingEnvironment. Lombok won't work.");
return null;
}
@@ -444,10 +430,8 @@ public class LombokProcessor extends AbstractProcessor {
* (directly or through a delegate field again)
*/
public JavacFiler getJavacFiler(Object filer) {
if (filer instanceof JavacFiler) {
return (JavacFiler) filer;
}
if (filer instanceof JavacFiler) return (JavacFiler) filer;
// try to find a "delegate" field in the object, and use this to check for a JavacFiler
for (Class<?> filerClass = filer.getClass(); filerClass != null; filerClass = filerClass.getSuperclass()) {
try {
@@ -456,15 +440,13 @@ public class LombokProcessor extends AbstractProcessor {
// delegate field was not found, try on superclass
}
}
processingEnv.getMessager().printMessage(Kind.WARNING,
"Can't get a JavacFiler from " + filer.getClass().getName() + ". Lombok won't work.");
"Can't get a JavacFiler from " + filer.getClass().getName() + ". Lombok won't work.");
return null;
}
private Object tryGetDelegateField(Class<?> delegateClass, Object instance) throws Exception {
Field field = delegateClass.getDeclaredField("delegate");
field.setAccessible(true);
return field.get(instance);
return Permit.getField(delegateClass, "delegate").get(instance);
}
}
+4 -4
View File
@@ -53,6 +53,8 @@ import com.sun.tools.javac.processing.JavacFiler;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Options;
import lombok.permit.Permit;
/**
* This processor should not be used. It used to be THE processor. This class is only there to warn people that something went wrong, and for the
* lombok developers to see if what the reason for those failures is.
@@ -101,8 +103,7 @@ public class Processor extends AbstractProcessor {
try {
JavacProcessingEnvironment environment = (JavacProcessingEnvironment) procEnv;
Options instance = Options.instance(environment.getContext());
Field field = Options.class.getDeclaredField("values");
field.setAccessible(true);
Field field = Permit.getField(Options.class, "values");
@SuppressWarnings("unchecked") Map<String, String> values = (Map<String, String>) field.get(instance);
if (values.isEmpty()) {
message.append("Options: empty\n\n");
@@ -125,8 +126,7 @@ public class Processor extends AbstractProcessor {
private void findServices(StringBuilder message, Filer filer) {
try {
Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager");
filerFileManagerField.setAccessible(true);
Field filerFileManagerField = Permit.getField(JavacFiler.class, "fileManager");
JavaFileManager jfm = (JavaFileManager) filerFileManagerField.get(filer);
ClassLoader processorClassLoader = jfm.hasLocation(ANNOTATION_PROCESSOR_PATH) ? jfm.getClassLoader(ANNOTATION_PROCESSOR_PATH) : jfm.getClassLoader(CLASS_PATH);
Enumeration<URL> resources = processorClassLoader.getResources("META-INF/services/javax.annotation.processing.Processor");
@@ -58,6 +58,7 @@ import lombok.experimental.Tolerate;
import lombok.javac.Javac;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.permit.Permit;
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
@@ -1049,10 +1050,9 @@ public class JavacHandlerUtil {
if (TYPE != null) return;
if (!in.getName().equals("com.sun.tools.javac.tree.JCTree$JCAnnotatedType")) return;
try {
CONSTRUCTOR = in.getDeclaredConstructor(List.class, JCExpression.class);
CONSTRUCTOR.setAccessible(true);
ANNOTATIONS = in.getDeclaredField("annotations");
UNDERLYING_TYPE = in.getDeclaredField("underlyingType");
CONSTRUCTOR = Permit.getConstructor(in, List.class, JCExpression.class);
ANNOTATIONS = Permit.getField(in, "annotations");
UNDERLYING_TYPE = Permit.getField(in, "underlyingType");
TYPE = in;
} catch (Exception ignore) {}
}
@@ -1102,9 +1102,9 @@ public class JavacHandlerUtil {
Method r = null;
Method e = null;
try {
f = ClassSymbol.class.getField("members_field");
r = f.getType().getMethod("remove", Symbol.class);
e = f.getType().getMethod("enter", Symbol.class);
f = Permit.getField(ClassSymbol.class, "members_field");
r = Permit.getMethod(f.getType(), "remove", Symbol.class);
e = Permit.getMethod(f.getType(), "enter", Symbol.class);
} catch (Exception ex) {}
membersField = f;
removeMethod = r;
+6 -5
View File
@@ -61,6 +61,7 @@ import lombok.javac.CommentCatcher;
import lombok.javac.Javac;
import lombok.javac.LombokOptions;
import lombok.javac.apt.LombokProcessor;
import lombok.permit.Permit;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.Todo;
@@ -638,7 +639,7 @@ public class Delombok {
private static final Field MODULE_FIELD = getModuleField();
private static Field getModuleField() {
try {
return JCCompilationUnit.class.getField("modle");
return Permit.getField(JCCompilationUnit.class, "modle");
} catch (NoSuchFieldException e) {
return null;
} catch (SecurityException e) {
@@ -808,10 +809,10 @@ public class Delombok {
private static Object callAttributeMethodOnJavaCompiler(JavaCompiler compiler, Todo arg) {
if (attributeMethod == null) {
try {
attributeMethod = JavaCompiler.class.getDeclaredMethod("attribute", java.util.Queue.class);
attributeMethod = Permit.getMethod(JavaCompiler.class, "attribute", java.util.Queue.class);
} catch (NoSuchMethodException e) {
try {
attributeMethod = JavaCompiler.class.getDeclaredMethod("attribute", com.sun.tools.javac.util.ListBuffer.class);
attributeMethod = Permit.getMethod(JavaCompiler.class, "attribute", com.sun.tools.javac.util.ListBuffer.class);
} catch (NoSuchMethodException e2) {
throw Lombok.sneakyThrow(e2);
}
@@ -830,10 +831,10 @@ public class Delombok {
private static void callFlowMethodOnJavaCompiler(JavaCompiler compiler, Object arg) {
if (flowMethod == null) {
try {
flowMethod = JavaCompiler.class.getDeclaredMethod("flow", java.util.Queue.class);
flowMethod = Permit.getMethod(JavaCompiler.class, "flow", java.util.Queue.class);
} catch (NoSuchMethodException e) {
try {
flowMethod = JavaCompiler.class.getDeclaredMethod("flow", com.sun.tools.javac.util.List.class);
flowMethod = Permit.getMethod(JavaCompiler.class, "flow", com.sun.tools.javac.util.List.class);
} catch (NoSuchMethodException e2) {
throw Lombok.sneakyThrow(e2);
}
@@ -36,6 +36,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import lombok.core.LombokApp;
import lombok.permit.Permit;
import org.mangosdk.spi.ProviderFor;
@@ -52,7 +53,7 @@ public class DelombokApp extends LombokApp {
return 1;
}
try {
loadDelombok(args).getMethod("main", String[].class).invoke(null, new Object[] {args.toArray(new String[0])});
Permit.getMethod(loadDelombok(args), "main", String[].class).invoke(null, new Object[] {args.toArray(new String[0])});
} catch (InvocationTargetException e1) {
Throwable t = e1.getCause();
if (t instanceof Error) throw (Error)t;
@@ -93,6 +93,7 @@ import com.sun.tools.javac.util.Position;
import lombok.javac.CommentInfo;
import lombok.javac.PackageName;
import lombok.permit.Permit;
import lombok.javac.CommentInfo.EndConnection;
import lombok.javac.CommentInfo.StartConnection;
import lombok.javac.JavacTreeMaker.TreeTag;
@@ -1335,7 +1336,6 @@ public class PrettyPrinter extends JCTree.Visitor {
static {
getExtendsClause = getMethod(JCClassDecl.class, "getExtendsClause", new Class<?>[0]);
getExtendsClause.setAccessible(true);
if (getJavaCompilerVersion() < 8) {
getEndPosition = getMethod(DiagnosticPosition.class, "getEndPosition", java.util.Map.class);
@@ -1350,11 +1350,11 @@ public class PrettyPrinter extends JCTree.Visitor {
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) {
@@ -1363,13 +1363,13 @@ public class PrettyPrinter extends JCTree.Visitor {
}
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);
}
@@ -1379,7 +1379,7 @@ public class PrettyPrinter extends JCTree.Visitor {
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) {
@@ -1418,11 +1418,10 @@ public class PrettyPrinter extends JCTree.Visitor {
Field f = c.get(fieldName);
if (f == null) {
try {
f = tClass.getDeclaredField(fieldName);
f = Permit.getField(tClass, fieldName);
} catch (Exception e) {
return defaultValue;
}
f.setAccessible(true);
c.put(fieldName, f);
}
@@ -30,6 +30,7 @@ import java.util.ArrayList;
import java.util.List;
import lombok.Lombok;
import lombok.permit.Permit;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
@@ -176,8 +177,7 @@ class Tasks {
} catch (ClassNotFoundException e) {
// If we get here, it isn't, and we should use the shadowloader.
Class<?> launcherMain = Class.forName("lombok.launch.Main");
Method m = launcherMain.getDeclaredMethod("createShadowClassLoader");
m.setAccessible(true);
Method m = Permit.getMethod(launcherMain, "createShadowClassLoader");
shadowLoader = (ClassLoader) m.invoke(null);
}
}
@@ -195,10 +195,9 @@ class Tasks {
try {
Object instance = shadowLoadClass("lombok.delombok.ant.DelombokTaskImpl").newInstance();
for (Field selfField : getClass().getDeclaredFields()) {
Permit.setAccessible(selfField);
if (selfField.isSynthetic() || Modifier.isStatic(selfField.getModifiers())) continue;
Field otherField = instance.getClass().getDeclaredField(selfField.getName());
otherField.setAccessible(true);
selfField.setAccessible(true);
Field otherField = Permit.getField(instance.getClass(), selfField.getName());
if (selfField.getName().equals("formatOptions")) {
List<String> rep = new ArrayList<String>();
for (Format f : formatOptions) {
@@ -211,8 +210,7 @@ class Tasks {
}
}
Method m = instance.getClass().getMethod("execute", Location.class);
m.setAccessible(true);
Method m = Permit.getMethod(instance.getClass(), "execute", Location.class);
m.invoke(instance, loc);
} catch (InvocationTargetException e) {
throw Lombok.sneakyThrow(e.getCause());
@@ -33,6 +33,7 @@ import java.util.List;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.agent.PatchExtensionMethod.Extension;
import lombok.experimental.ExtensionMethod;
import lombok.permit.Permit;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.internal.codeassist.InternalCompletionContext;
@@ -220,7 +221,7 @@ public class PatchExtensionMethodCompletionProposal {
return null;
}
}
private static Method accessMethod(Class<?> clazz, String methodName, Class<?> parameter) {
try {
return makeAccessible(clazz.getDeclaredMethod(methodName, parameter));
@@ -228,10 +229,9 @@ public class PatchExtensionMethodCompletionProposal {
return null;
}
}
private static <T extends AccessibleObject> T makeAccessible(T object) {
object.setAccessible(true);
return object;
return Permit.setAccessible(object);
}
}
}
@@ -43,6 +43,8 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import lombok.permit.Permit;
import java.lang.reflect.Field;
import static lombok.eclipse.Eclipse.poss;
@@ -196,8 +198,8 @@ public class PatchVal {
Field a = null, b = null;
try {
a = LocalDeclaration.class.getDeclaredField("$initCopy");
b = LocalDeclaration.class.getDeclaredField("$iterableCopy");
a = Permit.getField(LocalDeclaration.class, "$initCopy");
b = Permit.getField(LocalDeclaration.class, "$iterableCopy");
} catch (Throwable t) {
//ignore - no $initCopy exists when running in ecj.
}
@@ -30,6 +30,7 @@ import java.lang.reflect.Method;
import java.util.List;
import lombok.Lombok;
import lombok.permit.Permit;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.IExtendedModifier;
@@ -277,8 +278,7 @@ public class PatchValEclipse {
static {
Field f = null;
try {
f = Name.class.getDeclaredField("index");
f.setAccessible(true);
f = Permit.getField(Name.class, "index");
} catch (Throwable t) {
// Leave it null, in which case we don't set index. That'll result in error log messages but its better than crashing here.
}
@@ -308,24 +308,19 @@ public class PatchValEclipse {
Method h = null;
try {
a = LocalDeclaration.class.getDeclaredField("$initCopy");
b = LocalDeclaration.class.getDeclaredField("$iterableCopy");
a = Permit.getField(LocalDeclaration.class, "$initCopy");
b = Permit.getField(LocalDeclaration.class, "$iterableCopy");
} catch (Throwable t) {
//ignore - no $initCopy exists when running in ecj.
}
try {
c = Parser.class.getDeclaredField("astStack");
c.setAccessible(true);
d = Parser.class.getDeclaredField("astPtr");
d.setAccessible(true);
f = Modifier.class.getDeclaredConstructor(AST.class);
f.setAccessible(true);
g = MarkerAnnotation.class.getDeclaredConstructor(AST.class);
g.setAccessible(true);
c = Permit.getField(Parser.class, "astStack");
d = Permit.getField(Parser.class, "astPtr");
f = Permit.getConstructor(Modifier.class, AST.class);
g = Permit.getConstructor(MarkerAnnotation.class, AST.class);
Class<?> z = Class.forName("org.eclipse.jdt.core.dom.ASTConverter");
h = z.getDeclaredMethod("recordNodes", org.eclipse.jdt.core.dom.ASTNode.class, org.eclipse.jdt.internal.compiler.ast.ASTNode.class);
h.setAccessible(true);
h = Permit.getMethod(z, "recordNodes", org.eclipse.jdt.core.dom.ASTNode.class, org.eclipse.jdt.internal.compiler.ast.ASTNode.class);
} catch (Throwable t) {
// Most likely we're in ecj or some other plugin usage of the eclipse compiler. No need for this.
}
+3 -2
View File
@@ -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;
+3 -2
View File
@@ -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) {
+10 -10
View File
@@ -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;
}
+10 -11
View File
@@ -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);
+3 -1
View File
@@ -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;
}
@@ -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);
@@ -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);
@@ -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);
@@ -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);
+100
View File
@@ -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;
}
}
}
@@ -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;