diff options
author | Reinier Zwitserloot <r.zwitserloot@projectlombok.org> | 2020-11-13 04:37:27 +0100 |
---|---|---|
committer | Reinier Zwitserloot <r.zwitserloot@projectlombok.org> | 2020-11-13 04:44:39 +0100 |
commit | 3aace094f336393330ed275e1fb6d6c1f9187e14 (patch) | |
tree | 3c235a645f057a393194bf789fc4ce4bfaaef340 /src | |
parent | 219bb4bea5035c370614474f630dac454cfe4223 (diff) | |
download | lombok-3aace094f336393330ed275e1fb6d6c1f9187e14.tar.gz lombok-3aace094f336393330ed275e1fb6d6c1f9187e14.tar.bz2 lombok-3aace094f336393330ed275e1fb6d6c1f9187e14.zip |
[refactor] reflection code streamlined by sending it through the Permit class
Diffstat (limited to 'src')
20 files changed, 278 insertions, 190 deletions
diff --git a/src/core/lombok/core/AnnotationProcessor.java b/src/core/lombok/core/AnnotationProcessor.java index c72d1bb2..c9171284 100644 --- a/src/core/lombok/core/AnnotationProcessor.java +++ b/src/core/lombok/core/AnnotationProcessor.java @@ -174,7 +174,7 @@ public class AnnotationProcessor extends AbstractProcessor { if (!ClassLoader_lombokAlreadyAddedTo.getAndSet(environmentClassLoader, true)) { Method m = Permit.getMethod(environmentClassLoader.getClass(), "addURL", URL.class); URL selfUrl = new File(ClassRootFinder.findClassRootOfClass(AnnotationProcessor.class)).toURI().toURL(); - m.invoke(environmentClassLoader, selfUrl); + Permit.invoke(m, environmentClassLoader, selfUrl); } } diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index d53856af..73114c6c 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -286,23 +286,8 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { */ public static void addProblemToCompilationResult(char[] fileNameArray, CompilationResult result, boolean isWarning, String message, int sourceStart, int sourceEnd) { - try { - EcjReflectionCheck.addProblemToCompilationResult.invoke(null, fileNameArray, result, isWarning, message, sourceStart, sourceEnd); - } catch (NoClassDefFoundError e) { - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e); - } catch (NullPointerException e) { - if (!"false".equals(System.getProperty("lombok.debug.reflection", "false"))) { - e.initCause(EcjReflectionCheck.problemAddProblemToCompilationResult); - throw e; - } - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - } + + Permit.invokeSneaky(EcjReflectionCheck.problemAddProblemToCompilationResult, EcjReflectionCheck.addProblemToCompilationResult, null, fileNameArray, result, isWarning, message, sourceStart, sourceEnd); } public static Annotation[] getTopLevelTypeReferenceAnnotations(TypeReference tr) { @@ -310,14 +295,14 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { if (m == null) return null; Annotation[][] annss = null; try { - annss = (Annotation[][]) m.invoke(tr); + annss = (Annotation[][]) Permit.invoke(m, tr); if (annss != null) return annss[0]; } catch (Throwable ignore) {} try { Field f = EcjReflectionCheck.typeReferenceAnnotations; if (f == null) return null; - annss = (Annotation[][]) f.get(tr); + annss = (Annotation[][]) Permit.get(f, tr); if (annss == null) return null; return annss[annss.length - 1]; } catch (Throwable t) { diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 03f26341..5da7abfd 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -373,7 +373,7 @@ public class EclipseHandlerUtil { private static Class<?> getClass(String fqn) { try { return Class.forName(fqn); - } catch (Exception e) { + } catch (Throwable t) { return null; } } @@ -381,7 +381,7 @@ public class EclipseHandlerUtil { private static Field getField(Class<?> c, String fName) { try { return Permit.getField(c, fName); - } catch (Exception e) { + } catch (Throwable t) { return null; } } @@ -2309,18 +2309,10 @@ public class EclipseHandlerUtil { public static IntLiteral makeIntLiteral(char[] token, ASTNode source) { int pS = source == null ? 0 : source.sourceStart, pE = source == null ? 0 : source.sourceEnd; IntLiteral result; - try { - if (intLiteralConstructor != null) { - result = intLiteralConstructor.newInstance(token, pS, pE); - } else { - result = (IntLiteral) intLiteralFactoryMethod.invoke(null, token, pS, pE); - } - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } catch (InstantiationException e) { - throw Lombok.sneakyThrow(e); + if (intLiteralConstructor != null) { + result = Permit.newInstanceSneaky(intLiteralConstructor, token, pS, pE); + } else { + result = (IntLiteral) Permit.invokeSneaky(intLiteralFactoryMethod, null, token, pS, pE); } if (source != null) setGeneratedBy(result, source); @@ -2671,7 +2663,7 @@ public class EclipseHandlerUtil { try { Class.forName("org.eclipse.jdt.internal.core.CompilationUnit"); eclipseMode = true; - } catch (Exception e) { + } catch (Throwable t) { eclipseMode = false; } return eclipseMode; diff --git a/src/core/lombok/javac/Javac6BasedLombokOptions.java b/src/core/lombok/javac/Javac6BasedLombokOptions.java index fc73181c..93f448a7 100644 --- a/src/core/lombok/javac/Javac6BasedLombokOptions.java +++ b/src/core/lombok/javac/Javac6BasedLombokOptions.java @@ -58,7 +58,7 @@ public class Javac6BasedLombokOptions extends LombokOptions { @Override public void putJavacOption(String optionName, String value) { try { - options_put.invoke(this, optionName_valueOf.invoke(null, optionName), value); + Permit.invoke(options_put, this, Permit.invoke(optionName_valueOf, null, optionName), value); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Can't initialize Javac6-based lombok options due to reflection issue.", e); } catch (InvocationTargetException e) { diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 86ff7646..22373cbe 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -397,11 +397,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { } private JCTree getBody(JCTree jcTree) { - try { - return (JCTree) getBodyMethod(jcTree.getClass()).invoke(jcTree); - } catch (Exception e) { - throw Javac.sneakyThrow(e); - } + return (JCTree) Permit.invokeSneaky(getBodyMethod(jcTree.getClass()), jcTree); } private final static ConcurrentMap<Class<?>, Method> getBodyMethods = new ConcurrentHashMap<Class<?>, Method>(); @@ -662,42 +658,26 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { } @Override void error1(DiagnosticPosition pos, String message) { - try { - Object error = this.errorKey.invoke(diags, PROC_MESSAGER, new Object[] { message }); - errorMethod.invoke(log, multiple, pos, error); - } catch (Throwable t) { - //t.printStackTrace(); - } + Object error = Permit.invokeSneaky(this.errorKey, diags, PROC_MESSAGER, new Object[] { message }); + if (error != null) Permit.invokeSneaky(errorMethod, log, multiple, pos, error); } @Override void warning1(DiagnosticPosition pos, String message) { - try { - Object warning = this.warningKey.invoke(diags, PROC_MESSAGER, new Object[] { message }); - warningMethod.invoke(log, pos, warning); - } catch (Throwable t) { - //t.printStackTrace(); - } + Object warning = Permit.invokeSneaky(this.warningKey, diags, PROC_MESSAGER, new Object[] { message }); + if (warning != null) Permit.invokeSneaky(warningMethod, log, pos, warning); } @Override void mandatoryWarning1(DiagnosticPosition pos, String message) { - try { - Object warning = this.warningKey.invoke(diags, PROC_MESSAGER, new Object[] { message }); - mandatoryWarningMethod.invoke(log, pos, warning); - } catch (Throwable t) { - //t.printStackTrace(); - } + Object warning = Permit.invokeSneaky(this.warningKey, diags, PROC_MESSAGER, new Object[] { message }); + if (warning != null) Permit.invokeSneaky(mandatoryWarningMethod, log, pos, warning); } @Override void note(DiagnosticPosition pos, String message) { - try { - Object note = this.noteKey.invoke(diags, PROC_MESSAGER, new Object[] { message }); - noteMethod.invoke(log, pos, note); - } catch (Throwable t) { - //t.printStackTrace(); - } + Object note = Permit.invokeSneaky(this.noteKey, diags, PROC_MESSAGER, new Object[] { message }); + if (note != null) Permit.invokeSneaky(noteMethod, log, pos, note); } } } diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index 6b2f4637..63ca69dd 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -25,7 +25,6 @@ import static lombok.javac.Javac.*; import static lombok.javac.JavacTreeMaker.TypeTag.typeTag; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayDeque; import java.util.Collection; @@ -65,7 +64,6 @@ import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Name; -import lombok.Lombok; import lombok.core.debug.AssertionLogger; import lombok.permit.Permit; @@ -251,27 +249,27 @@ public class JavacResolution { private static class ReflectiveAccess { private static Method UPPER_BOUND; + private static Throwable initError; static { Method upperBound = null; try { upperBound = Permit.getMethod(Types.class, "upperBound", Type.class); - } catch (Throwable ignore) {} + } catch (Throwable e) { + initError = e; + } + if (upperBound == null) try { upperBound = Permit.getMethod(Types.class, "wildUpperBound", Type.class); - } catch (Throwable ignore) {} + } catch (Throwable e) { + initError = e; + } UPPER_BOUND = upperBound; } public static Type Types_upperBound(Types types, Type type) { - try { - return (Type) UPPER_BOUND.invoke(types, type); - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); - } catch (Exception e) { - throw Lombok.sneakyThrow(e); - } + return (Type) Permit.invokeSneaky(initError, UPPER_BOUND, types, type); } } diff --git a/src/core/lombok/javac/apt/InterceptingJavaFileObject.java b/src/core/lombok/javac/apt/InterceptingJavaFileObject.java index 368928d4..403b5672 100644 --- a/src/core/lombok/javac/apt/InterceptingJavaFileObject.java +++ b/src/core/lombok/javac/apt/InterceptingJavaFileObject.java @@ -38,6 +38,7 @@ import javax.tools.JavaFileObject; import lombok.Lombok; import lombok.core.DiagnosticsReceiver; import lombok.core.PostCompiler; +import lombok.permit.Permit; final class InterceptingJavaFileObject implements LombokFileObject { private final JavaFileObject delegate; @@ -63,16 +64,8 @@ final class InterceptingJavaFileObject implements LombokFileObject { } @Override public CharsetDecoder getDecoder(boolean ignoreEncodingErrors) { - if (decoderMethod == null) { - throw new UnsupportedOperationException(); - } - try { - return (CharsetDecoder) decoderMethod.invoke(delegate, ignoreEncodingErrors); - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e); - } + if (decoderMethod == null) throw new UnsupportedOperationException(); + return (CharsetDecoder) Permit.invokeSneaky(decoderMethod, delegate, ignoreEncodingErrors); } @Override public boolean equals(Object obj) { diff --git a/src/core/lombok/javac/apt/LombokProcessor.java b/src/core/lombok/javac/apt/LombokProcessor.java index 67df5b20..485b82a4 100644 --- a/src/core/lombok/javac/apt/LombokProcessor.java +++ b/src/core/lombok/javac/apt/LombokProcessor.java @@ -156,10 +156,10 @@ public class LombokProcessor extends AbstractProcessor { disablePartialReparseInNetBeansEditor(context); try { Method keyMethod = Permit.getMethod(Context.class, "key", Class.class); - Object key = keyMethod.invoke(context, JavaFileManager.class); + Object key = Permit.invoke(keyMethod, context, JavaFileManager.class); Field htField = Permit.getField(Context.class, "ht"); @SuppressWarnings("unchecked") - Map<Object,Object> ht = (Map<Object,Object>) htField.get(context); + Map<Object,Object> ht = (Map<Object,Object>) Permit.get(htField, context); final JavaFileManager originalFiler = (JavaFileManager) ht.get(key); if (!(originalFiler instanceof InterceptingJavaFileManager)) { final Messager messager = processingEnv.getMessager(); @@ -182,10 +182,10 @@ public class LombokProcessor extends AbstractProcessor { private void replaceFileManagerJdk9(Context context, JavaFileManager newFiler) { try { - JavaCompiler compiler = (JavaCompiler) Permit.getMethod(JavaCompiler.class, "instance", Context.class).invoke(null, context); + JavaCompiler compiler = (JavaCompiler) Permit.invoke(Permit.getMethod(JavaCompiler.class, "instance", Context.class), null, context); try { Field fileManagerField = Permit.getField(JavaCompiler.class, "fileManager"); - fileManagerField.set(compiler, newFiler); + Permit.set(fileManagerField, compiler, newFiler); } catch (Exception e) {} @@ -193,7 +193,7 @@ public class LombokProcessor extends AbstractProcessor { Field writerField = Permit.getField(JavaCompiler.class, "writer"); ClassWriter writer = (ClassWriter) writerField.get(compiler); Field fileManagerField = Permit.getField(ClassWriter.class, "fileManager"); - fileManagerField.set(writer, newFiler); + Permit.set(fileManagerField, writer, newFiler); } catch (Exception e) {} } @@ -215,8 +215,8 @@ public class LombokProcessor extends AbstractProcessor { private void disablePartialReparseInNetBeansEditor(Context context) { try { Class<?> cancelServiceClass = Class.forName("com.sun.tools.javac.util.CancelService"); - Method cancelServiceInstace = Permit.getMethod(cancelServiceClass, "instance", Context.class); - Object cancelService = cancelServiceInstace.invoke(null, context); + Method cancelServiceInstance = Permit.getMethod(cancelServiceClass, "instance", Context.class); + Object cancelService = Permit.invoke(cancelServiceInstance, null, context); if (cancelService == null) return; Field parserField = Permit.getField(cancelService.getClass(), "parser"); Object parser = parserField.get(cancelService); @@ -388,8 +388,8 @@ public class LombokProcessor extends AbstractProcessor { try { if (qualifiedNamableClass == null) qualifiedNamableClass = Class.forName("javax.lang.model.element.QualifiedNamable"); if (!qualifiedNamableClass.isInstance(element)) return null; - if (qualifiedNamableQualifiedNameMethod == null) qualifiedNamableQualifiedNameMethod = qualifiedNamableClass.getMethod("getQualifiedName"); - String name = qualifiedNamableQualifiedNameMethod.invoke(element).toString().trim(); + if (qualifiedNamableQualifiedNameMethod == null) qualifiedNamableQualifiedNameMethod = Permit.getMethod(qualifiedNamableClass, "getQualifiedName"); + String name = Permit.invoke(qualifiedNamableQualifiedNameMethod, element).toString().trim(); return name.isEmpty() ? null : name; } catch (ClassNotFoundException e) { return null; diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java index d6e76ab1..ac414fbb 100644 --- a/src/core/lombok/javac/handlers/HandleDelegate.java +++ b/src/core/lombok/javac/handlers/HandleDelegate.java @@ -81,6 +81,7 @@ import lombok.javac.JavacResolution; import lombok.javac.JavacResolution.TypeNotConvertibleException; import lombok.javac.JavacTreeMaker; import lombok.javac.ResolutionResetNeeded; +import lombok.permit.Permit; @ProviderFor(JavacAnnotationHandler.class) @HandlerPriority(HandleDelegate.HANDLE_DELEGATE_PRIORITY) //2^16; to make sure that we also delegate generated methods. @@ -466,7 +467,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { static { Method m = null; try { - m = Type.class.getDeclaredMethod("unannotatedType"); + m = Permit.getMethod(Type.class, "unannotatedType"); } catch (Exception e) {/* ignore */} unannotated = m; } @@ -474,7 +475,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> { static Type unannotatedType(Type t) { if (unannotated == null) return t; try { - return (Type) unannotated.invoke(t); + return (Type) Permit.invoke(unannotated, t); } catch (Exception e) { return t; } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 8d21f903..df1eb438 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1183,7 +1183,7 @@ public class JavacHandlerUtil { try { Scope scope = (Scope) membersField.get(from); if (scope == null) return; - removeMethod.invoke(scope, toRemove); + Permit.invoke(removeMethod, scope, toRemove); } catch (Exception e) {} } @@ -1192,7 +1192,7 @@ public class JavacHandlerUtil { try { Scope scope = (Scope) membersField.get(from); if (scope == null) return; - enterMethod.invoke(scope, toEnter); + Permit.invoke(enterMethod, scope, toEnter); } catch (Exception e) {} } } diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java index 6c15068a..6b745015 100755 --- a/src/delombok/lombok/delombok/Delombok.java +++ b/src/delombok/lombok/delombok/Delombok.java @@ -34,7 +34,6 @@ import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; import java.net.URLDecoder; @@ -841,12 +840,8 @@ public class Delombok { } } } - try { - return attributeMethod.invoke(compiler, arg); - } catch (Exception e) { - if (e instanceof InvocationTargetException) throw Lombok.sneakyThrow(e.getCause()); - throw Lombok.sneakyThrow(e); - } + + return Permit.invokeSneaky(attributeMethod, compiler, arg); } private static Method flowMethod; @@ -863,12 +858,8 @@ public class Delombok { } } } - try { - flowMethod.invoke(compiler, arg); - } catch (Exception e) { - if (e instanceof InvocationTargetException) throw Lombok.sneakyThrow(e.getCause()); - throw Lombok.sneakyThrow(e); - } + + Permit.invokeSneaky(flowMethod, compiler, arg); } private static String canonical(File dir) { diff --git a/src/delombok/lombok/delombok/DelombokApp.java b/src/delombok/lombok/delombok/DelombokApp.java index da1975b4..8467bf77 100644 --- a/src/delombok/lombok/delombok/DelombokApp.java +++ b/src/delombok/lombok/delombok/DelombokApp.java @@ -53,11 +53,11 @@ public class DelombokApp extends LombokApp { return 1; } try { - Permit.getMethod(loadDelombok(args), "main", String[].class).invoke(null, new Object[] {args.toArray(new String[0])}); + Permit.invoke(Permit.getMethod(loadDelombok(args), "main", String[].class), null, new Object[] {args.toArray(new String[0])}); } catch (InvocationTargetException e1) { Throwable t = e1.getCause(); - if (t instanceof Error) throw (Error)t; - if (t instanceof Exception) throw (Exception)t; + if (t instanceof Error) throw (Error) t; + if (t instanceof Exception) throw (Exception) t; throw e1; } return 0; diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 54fa4ebf..9f47e5ec 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1547,13 +1547,7 @@ public class PrettyPrinter extends JCTree.Visitor { } public static JCTree getExtendsClause(JCClassDecl decl) { - try { - return (JCTree) getExtendsClause.invoke(decl); - } catch (IllegalAccessException e) { - throw sneakyThrow(e); - } catch (InvocationTargetException e) { - throw sneakyThrow(e.getCause()); - } + return (JCTree) Permit.invokeSneaky(getExtendsClause, decl); } static RuntimeException sneakyThrow(Throwable t) { diff --git a/src/delombok/lombok/delombok/ant/DelombokTask.java b/src/delombok/lombok/delombok/ant/DelombokTask.java index defd1709..7c585836 100644 --- a/src/delombok/lombok/delombok/ant/DelombokTask.java +++ b/src/delombok/lombok/delombok/ant/DelombokTask.java @@ -177,9 +177,11 @@ class Tasks { } return Class.forName(name, true, shadowLoader); - } catch (Exception e) { - if (e instanceof RuntimeException) throw (RuntimeException) e; - throw new RuntimeException(e); + } catch (Throwable t) { + if (t instanceof InvocationTargetException) t = t.getCause(); + if (t instanceof RuntimeException) throw (RuntimeException) t; + if (t instanceof Error) throw (Error) t; + throw new RuntimeException(t); } } @@ -207,10 +209,10 @@ class Tasks { Method m = instance.getClass().getMethod("execute", Location.class); m.invoke(instance, loc); - } catch (Exception e) { - Throwable t = (e instanceof InvocationTargetException) ? e.getCause() : e; - if (t instanceof Error) throw (Error) t; + } catch (Throwable t) { + if (t instanceof InvocationTargetException) t = t.getCause(); if (t instanceof RuntimeException) throw (RuntimeException) t; + if (t instanceof Error) throw (Error) t; throw new RuntimeException(t); } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java index b90d5762..99367a22 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java @@ -101,6 +101,7 @@ import lombok.eclipse.EclipseNode; import lombok.eclipse.TransformEclipseAST; import lombok.eclipse.handlers.SetGeneratedByVisitor; import lombok.patcher.Symbols; +import lombok.permit.Permit; public class PatchDelegate { @@ -846,18 +847,20 @@ public class PatchDelegate { private static final class Reflection { public static final Method classScopeBuildFieldsAndMethodsMethod; - + public static final Throwable initCause; static { Method m = null; + Throwable c = null; try { - m = ClassScope.class.getDeclaredMethod("buildFieldsAndMethods"); - m.setAccessible(true); + m = Permit.getMethod(ClassScope.class, "buildFieldsAndMethods"); } catch (Throwable t) { + c = 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. } classScopeBuildFieldsAndMethodsMethod = m; + initCause = c; } } @@ -894,16 +897,14 @@ public class PatchDelegate { ClassScope cs = ((SourceTypeBinding)inner).scope; if (cs != null) { try { - Reflection.classScopeBuildFieldsAndMethodsMethod.invoke(cs); + Permit.invoke(Reflection.initCause, Reflection.classScopeBuildFieldsAndMethodsMethod, cs); } catch (Exception e) { // See 'Reflection' class for why we ignore this exception. } } } - if (!(binding instanceof ReferenceBinding)) { - return; - } + if (!(binding instanceof ReferenceBinding)) return; ReferenceBinding rb = (ReferenceBinding) binding; MethodBinding[] availableMethods = rb.availableMethods(); diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegatePortal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegatePortal.java index 89b02f01..3d8c86c9 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegatePortal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegatePortal.java @@ -21,10 +21,9 @@ */ package lombok.eclipse.agent; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import lombok.Lombok; +import lombok.permit.Permit; public class PatchDelegatePortal { static final String CLASS_SCOPE = "org.eclipse.jdt.internal.compiler.lookup.ClassScope"; @@ -32,47 +31,13 @@ public class PatchDelegatePortal { static final String SOURCE_TYPE_ELEMENT_INFO = "org.eclipse.jdt.internal.core.SourceTypeElementInfo"; public static boolean handleDelegateForType(Object classScope) { - try { - return (Boolean) Reflection.handleDelegateForType.invoke(null, classScope); - } catch (NoClassDefFoundError e) { - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - return false; - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); - } catch (NullPointerException e) { - if (!"false".equals(System.getProperty("lombok.debug.reflection", "false"))) { - e.initCause(Reflection.problem); - throw e; - } - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - return false; - } + Boolean v = (Boolean) Permit.invokeSneaky(Reflection.problem, Reflection.handleDelegateForType, null, classScope); + if (v == null) return false; + return v.booleanValue(); } public static Object[] getChildren(Object returnValue, Object javaElement) { - try { - return (Object[]) Reflection.getChildren.invoke(null, returnValue, javaElement); - } catch (NoClassDefFoundError e) { - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - return (Object[]) returnValue; - } catch (IllegalAccessException e) { - throw Lombok.sneakyThrow(e); - } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); - } catch (NullPointerException e) { - if (!"false".equals(System.getProperty("lombok.debug.reflection", "false"))) { - e.initCause(Reflection.problem); - throw e; - } - //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly - //do anything useful here. - return (Object[]) returnValue; - } + return (Object[]) Permit.invokeSneaky(Reflection.problem, Reflection.getChildren, null, returnValue, javaElement); } private static final class Reflection { @@ -84,8 +49,8 @@ public class PatchDelegatePortal { Method m = null, n = null; Throwable problem_ = null; try { - m = PatchDelegate.class.getMethod("handleDelegateForType", Class.forName(CLASS_SCOPE)); - n = PatchDelegate.class.getMethod("getChildren", Class.forName(I_JAVA_ELEMENT_ARRAY), Class.forName(SOURCE_TYPE_ELEMENT_INFO)); + m = Permit.getMethod(PatchDelegate.class, "handleDelegateForType", Class.forName(CLASS_SCOPE)); + n = Permit.getMethod(PatchDelegate.class, "getChildren", Class.forName(I_JAVA_ELEMENT_ARRAY), Class.forName(SOURCE_TYPE_ELEMENT_INFO)); } 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/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java index 0f602671..c916ca26 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java @@ -99,13 +99,13 @@ public class PatchExtensionMethod { private static final Method shortMethod = getMethod("invalidMethod", MessageSend.class, MethodBinding.class); private static final Method longMethod = getMethod("invalidMethod", MessageSend.class, MethodBinding.class, Scope.class); + private static Throwable initProblem; private static Method getMethod(String name, Class<?>... types) { try { - Method m = ProblemReporter.class.getMethod(name, types); - m.setAccessible(true); - return m; + return Permit.getMethod(ProblemReporter.class, name, types); } catch (Exception e) { + initProblem = e; return null; } } @@ -120,8 +120,9 @@ public class PatchExtensionMethod { static void invoke(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method, Scope scope) { if (messageSend != null) { try { - if (shortMethod != null) shortMethod.invoke(problemReporter, messageSend, method); - else if (longMethod != null) longMethod.invoke(problemReporter, messageSend, method, scope); + if (shortMethod != null) Permit.invoke(initProblem, shortMethod, problemReporter, messageSend, method); + else if (longMethod != null) Permit.invoke(initProblem, longMethod, problemReporter, messageSend, method, scope); + else Permit.reportReflectionProblem(initProblem, "method named 'invalidMethod' not found in ProblemReporter.class"); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java index 08a42d1c..1b94d1b9 100755 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java @@ -198,7 +198,7 @@ public class PatchExtensionMethodCompletionProposal { public static final Field completionEngineField; public static final Field nameLookupField; public static final Method createJavaCompletionProposalMethod; - + static { replacementOffsetField = accessField(AbstractJavaCompletionProposal.class, "fReplacementOffset"); contextField = accessField(CompletionProposalCollector.class, "fContext"); diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodPortal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodPortal.java index 90a23c20..82df71f6 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodPortal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodPortal.java @@ -54,7 +54,7 @@ public class PatchExtensionMethodPortal { //do anything useful here. } } - + public static void invalidMethod(Object problemReporter, Object messageSend, Object method) { try { Reflection.invalidMethod.invoke(null, problemReporter, messageSend, method); @@ -62,23 +62,37 @@ public class PatchExtensionMethodPortal { //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly //do anything useful here. } catch (IllegalAccessException e) { + handleReflectionDebug(e); throw Lombok.sneakyThrow(e); } catch (InvocationTargetException e) { + handleReflectionDebug(e.getCause()); throw Lombok.sneakyThrow(e.getCause()); } catch (NullPointerException e) { - if (!"false".equals(System.getProperty("lombok.debug.reflection", "false"))) { - e.initCause(Reflection.problem); - throw e; - } + handleReflectionDebug(e); //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly //do anything useful here. } } - + + public static boolean isDebugReflection() { + return !"false".equals(System.getProperty("lombok.debug.reflection", "false")); + } + + public static void handleReflectionDebug(Throwable t) { + if (!isDebugReflection()) return; + + System.err.println("** LOMBOK REFLECTION exception: " + t.getClass() + ": " + (t.getMessage() == null ? "(no message)" : t.getMessage())); + t.printStackTrace(System.err); + if (Reflection.problem != null) { + System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: "); + Reflection.problem.printStackTrace(System.err); + } + } + private static final class Reflection { public static final Method resolveType, errorNoMethodFor, invalidMethod; public static final Throwable problem; - + static { Method m = null, n = null, o = null; Throwable problem_ = null; diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java index 407c3922..c0006559 100644 --- a/src/utils/lombok/permit/Permit.java +++ b/src/utils/lombok/permit/Permit.java @@ -24,11 +24,22 @@ package lombok.permit; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.URL; +import javax.tools.JavaFileManager; + +import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.TypeReference; + +import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; +import lombok.Lombok; + // 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"}) @@ -158,4 +169,164 @@ public class Permit { return null; } } + + public static boolean isDebugReflection() { + return !"false".equals(System.getProperty("lombok.debug.reflection", "false")); + } + + public static void handleReflectionDebug(Throwable t, Throwable initError) { + if (!isDebugReflection()) return; + + System.err.println("** LOMBOK REFLECTION exception: " + t.getClass() + ": " + (t.getMessage() == null ? "(no message)" : t.getMessage())); + t.printStackTrace(System.err); + if (initError != null) { + System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: "); + initError.printStackTrace(System.err); + } + } + + public static Object invoke(Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException { + return invoke(null, m, receiver, args); + } + + public static Object invoke(Throwable initError, Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException { + try { + return m.invoke(receiver, args); + } catch (IllegalAccessException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (RuntimeException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (Error e) { + handleReflectionDebug(e, initError); + throw e; + } + } + + public static Object invokeSneaky(Method m, Object receiver, Object... args) { + return invokeSneaky(null, m, receiver, args); + } + + public static Object invokeSneaky(Throwable initError, Method m, Object receiver, Object... args) { + try { + return m.invoke(receiver, args); + } catch (NoClassDefFoundError e) { + handleReflectionDebug(e, initError); + //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly + //do anything useful here. + return null; + } catch (NullPointerException e) { + handleReflectionDebug(e, initError); + //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly + //do anything useful here. + return null; + } catch (IllegalAccessException e) { + handleReflectionDebug(e, initError); + throw Lombok.sneakyThrow(e); + } catch (InvocationTargetException e) { + throw Lombok.sneakyThrow(e.getCause()); + } catch (RuntimeException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (Error e) { + handleReflectionDebug(e, initError); + throw e; + } + } + + public static <T> T newInstance(Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException { + return newInstance(null, c, args); + } + + public static <T> T newInstance(Throwable initError, Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException { + try { + return c.newInstance(args); + } catch (IllegalAccessException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (InstantiationException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (RuntimeException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (Error e) { + handleReflectionDebug(e, initError); + throw e; + } + } + + public static <T> T newInstanceSneaky(Constructor<T> c, Object... args) { + return newInstanceSneaky(null, c, args); + } + + public static <T> T newInstanceSneaky(Throwable initError, Constructor<T> c, Object... args) { + try { + return c.newInstance(args); + } catch (NoClassDefFoundError e) { + handleReflectionDebug(e, initError); + //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly + //do anything useful here. + return null; + } catch (NullPointerException e) { + handleReflectionDebug(e, initError); + //ignore, we don't have access to the correct ECJ classes, so lombok can't possibly + //do anything useful here. + return null; + } catch (IllegalAccessException e) { + handleReflectionDebug(e, initError); + throw Lombok.sneakyThrow(e); + } catch (InstantiationException e) { + handleReflectionDebug(e, initError); + throw Lombok.sneakyThrow(e); + } catch (InvocationTargetException e) { + throw Lombok.sneakyThrow(e.getCause()); + } catch (RuntimeException e) { + handleReflectionDebug(e, initError); + throw e; + } catch (Error e) { + handleReflectionDebug(e, initError); + throw e; + } + } + + public static Object get(Field f, Object receiver) throws IllegalAccessException { + try { + return f.get(receiver); + } catch (IllegalAccessException e) { + handleReflectionDebug(e, null); + throw e; + } catch (RuntimeException e) { + handleReflectionDebug(e, null); + throw e; + } catch (Error e) { + handleReflectionDebug(e, null); + throw e; + } + } + + public static void set(Field f, Object receiver, Object newValue) throws IllegalAccessException { + try { + f.set(receiver, newValue); + } catch (IllegalAccessException e) { + handleReflectionDebug(e, null); + throw e; + } catch (RuntimeException e) { + handleReflectionDebug(e, null); + throw e; + } catch (Error e) { + handleReflectionDebug(e, null); + throw e; + } + } + + public static void reportReflectionProblem(Throwable initError, String msg) { + if (!isDebugReflection()) return; + System.err.println("** LOMBOK REFLECTION issue: " + msg); + if (initError != null) { + System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: "); + initError.printStackTrace(System.err); + } + } } |