diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2018-10-29 23:13:52 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2018-10-29 23:13:59 +0100 |
commit | eca219ee6433cd964f0549a114a791ca4eb9f0fa (patch) | |
tree | 20f6fed449504fbf5dbc52bd15ff3f2458dd90f8 /src | |
parent | 182cb0cb9e8db6341fb4633c3849b5e90ba6d088 (diff) | |
download | lombok-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')
32 files changed, 276 insertions, 188 deletions
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index fe7a4330..afbba1e8 100644 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -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)); } } diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java index 293bfef6..363952a4 100644 --- a/src/core/lombok/core/AnnotationProcessor.java +++ b/src/core/lombok/core/AnnotationProcessor.java @@ -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); } diff --git a/src/core/lombok/core/AnnotationValues.java b/src/core/lombok/core/AnnotationValues.java index a24330fa..eec5abd8 100644 --- a/src/core/lombok/core/AnnotationValues.java +++ b/src/core/lombok/core/AnnotationValues.java @@ -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; } diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index 7cd2e400..1ba26338 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -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. diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java index 323fc171..e5edba64 100644 --- a/src/core/lombok/eclipse/TransformEclipseAST.java +++ b/src/core/lombok/eclipse/TransformEclipseAST.java @@ -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. } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 5d582aad..c69b3d0f 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -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 } diff --git a/src/core/lombok/javac/CompilerMessageSuppressor.java b/src/core/lombok/javac/CompilerMessageSuppressor.java index 391ec64a..02dc6c26 100644 --- a/src/core/lombok/javac/CompilerMessageSuppressor.java +++ b/src/core/lombok/javac/CompilerMessageSuppressor.java @@ -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; } } diff --git a/src/core/lombok/javac/Javac6BasedLombokOptions.java b/src/core/lombok/javac/Javac6BasedLombokOptions.java index cefb89ff..fc73181c 100644 --- a/src/core/lombok/javac/Javac6BasedLombokOptions.java +++ b/src/core/lombok/javac/Javac6BasedLombokOptions.java @@ -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); } diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 091612cc..9a5305a6 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -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(); } diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 8cc239e1..abbf6726 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -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; diff --git a/src/core/lombok/javac/apt/LombokFileObjects.java b/src/core/lombok/javac/apt/LombokFileObjects.java index aba10540..28d3c9fa 100644 --- a/src/core/lombok/javac/apt/LombokFileObjects.java +++ b/src/core/lombok/javac/apt/LombokFileObjects.java @@ -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() {} diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java index 247d0560..a3d1dfcf 100644 --- a/src/core/lombok/javac/apt/LombokProcessor.java +++ b/src/core/lombok/javac/apt/LombokProcessor.java @@ -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); } } diff --git a/src/core/lombok/javac/apt/Processor.java b/src/core/lombok/javac/apt/Processor.java index 7a187148..f15bf74c 100644 --- a/src/core/lombok/javac/apt/Processor.java +++ b/src/core/lombok/javac/apt/Processor.java @@ -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"); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index e4e40095..c97c7ede 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -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; diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 0b97b4be..69898668 100644 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -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); } diff --git a/src/delombok/lombok/delombok/DelombokApp.java b/src/delombok/lombok/delombok/DelombokApp.java index 2ba4c6ed..da1975b4 100644 --- a/src/delombok/lombok/delombok/DelombokApp.java +++ b/src/delombok/lombok/delombok/DelombokApp.java @@ -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; diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 4261a558..3fb1f1b1 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -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); } diff --git a/src/delombok/lombok/delombok/ant/DelombokTask.java b/src/delombok/lombok/delombok/ant/DelombokTask.java index adaf43dd..3828a5db 100644 --- a/src/delombok/lombok/delombok/ant/DelombokTask.java +++ b/src/delombok/lombok/delombok/ant/DelombokTask.java @@ -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()); diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java index c11a49cd..ace97a4d 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java @@ -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); } } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index fee104d3..8d581819 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -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. } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java index 99447bae..fc6e7de2 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java @@ -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. } 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 |