aboutsummaryrefslogtreecommitdiff
path: root/src/eclipseAgent/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/eclipseAgent/lombok')
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java72
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java128
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java249
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java75
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java53
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java4
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposalPortal.java3
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java384
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java53
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java93
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java21
-rw-r--r--src/eclipseAgent/lombok/launch/PatchFixesHider.java671
12 files changed, 1263 insertions, 543 deletions
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java
new file mode 100644
index 00000000..aa01c13d
--- /dev/null
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcher.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.agent;
+
+import lombok.patcher.ClassRootFinder;
+import lombok.patcher.Hook;
+import lombok.patcher.MethodTarget;
+import lombok.patcher.ScriptManager;
+import lombok.patcher.StackRequest;
+import lombok.patcher.scripts.ScriptBuilder;
+
+public class EclipseLoaderPatcher {
+ private static final String TRANSPLANTS_CLASS_NAME = "lombok.eclipse.agent.EclipseLoaderPatcherTransplants";
+
+ public static void patchEquinoxLoaders(ScriptManager sm, Class<?> launchingContext) {
+ sm.addScript(ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader", "loadClass",
+ "java.lang.Class", "java.lang.String", "boolean"))
+ .target(new MethodTarget("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader", "loadClass",
+ "java.lang.Class", "java.lang.String", "boolean"))
+ .target(new MethodTarget("org.eclipse.osgi.internal.loader.ModuleClassLoader", "loadClass",
+ "java.lang.Class", "java.lang.String", "boolean"))
+ .decisionMethod(new Hook(TRANSPLANTS_CLASS_NAME, "overrideLoadDecide", "boolean", "java.lang.ClassLoader", "java.lang.String", "boolean"))
+ .valueMethod(new Hook(TRANSPLANTS_CLASS_NAME, "overrideLoadResult", "java.lang.Class", "java.lang.ClassLoader", "java.lang.String", "boolean"))
+ .transplant()
+ .request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build());
+
+ sm.addScript(ScriptBuilder.addField().setPublic().setVolatile()
+ .fieldType("Ljava/lang/ClassLoader;")
+ .fieldName("lombok$shadowLoader")
+ .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader")
+ .targetClass("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader")
+ .targetClass("org.eclipse.osgi.internal.loader.ModuleClassLoader")
+ .build());
+
+ sm.addScript(ScriptBuilder.addField().setPublic().setVolatile().setStatic()
+ .fieldType("Ljava/lang/Class;")
+ .fieldName("lombok$shadowLoaderClass")
+ .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader")
+ .targetClass("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader")
+ .targetClass("org.eclipse.osgi.internal.loader.ModuleClassLoader")
+ .build());
+
+ sm.addScript(ScriptBuilder.addField().setPublic().setStatic().setFinal()
+ .fieldType("Ljava/lang/String;")
+ .fieldName("lombok$location")
+ .targetClass("org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader")
+ .targetClass("org.eclipse.osgi.framework.adapter.core.AbstractClassLoader")
+ .targetClass("org.eclipse.osgi.internal.loader.ModuleClassLoader")
+ .value(ClassRootFinder.findClassRootOfClass(launchingContext))
+ .build());
+ }
+}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
new file mode 100644
index 00000000..ea72f56a
--- /dev/null
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipseLoaderPatcherTransplants.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.agent;
+
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+/**
+ * Contains all the code to be transplanted into eclipse.
+ *
+ * Do not use:
+ *
+ * * Annotations
+ * * Generics
+ * * Varargs
+ * * Auto (un)boxing
+ * * class literals
+ *
+ * The above because this code is compiled with -source 1.4, and is transplanted.
+ *
+ * NB: The suppress warnings will be stripped out before compilation.
+ */
+@SuppressWarnings("all")
+public class EclipseLoaderPatcherTransplants {
+ public static boolean overrideLoadDecide(ClassLoader original, String name, boolean resolve) {
+ return name.startsWith("lombok.");
+ }
+
+ public static Class overrideLoadResult(ClassLoader original, String name, boolean resolve) throws ClassNotFoundException {
+ try {
+ Field shadowLoaderField = original.getClass().getField("lombok$shadowLoader");
+ ClassLoader shadowLoader = (ClassLoader) shadowLoaderField.get(original);
+ if (shadowLoader == null) {
+ synchronized ("lombok$shadowLoader$globalLock".intern()) {
+ shadowLoader = (ClassLoader) shadowLoaderField.get(original);
+ if (shadowLoader == null) {
+ Class shadowClassLoaderClass = (Class) original.getClass().getField("lombok$shadowLoaderClass").get(null);
+ Class classLoaderClass = Class.forName("java.lang.ClassLoader");
+ String jarLoc = (String) original.getClass().getField("lombok$location").get(null);
+ if (shadowClassLoaderClass == null) {
+ JarFile jf = new JarFile(jarLoc);
+ InputStream in = null;
+ try {
+ ZipEntry entry = jf.getEntry("lombok/launch/ShadowClassLoader.class");
+ in = jf.getInputStream(entry);
+ byte[] bytes = new byte[65536];
+ int len = 0;
+ while (true) {
+ int r = in.read(bytes, len, bytes.length - len);
+ if (r == -1) break;
+ len += r;
+ if (len == bytes.length) throw new IllegalStateException("lombok.launch.ShadowClassLoader too large.");
+ }
+ in.close();
+ {
+ Class[] paramTypes = new Class[4];
+ paramTypes[0] = "".getClass();
+ paramTypes[1] = new byte[0].getClass();
+ paramTypes[2] = Integer.TYPE;
+ paramTypes[3] = paramTypes[2];
+ Method defineClassMethod = classLoaderClass.getDeclaredMethod("defineClass", paramTypes);
+ defineClassMethod.setAccessible(true);
+ shadowClassLoaderClass = (Class) defineClassMethod.invoke(original, new Object[] {"lombok.launch.ShadowClassLoader", bytes, new Integer(0), new Integer(len)});
+ original.getClass().getField("lombok$shadowLoaderClass").set(null, shadowClassLoaderClass);
+ }
+ } finally {
+ if (in != null) in.close();
+ jf.close();
+ }
+ }
+ Class[] paramTypes = new Class[5];
+ paramTypes[0] = classLoaderClass;
+ paramTypes[1] = "".getClass();
+ paramTypes[2] = paramTypes[1];
+ paramTypes[3] = Class.forName("java.util.List");
+ paramTypes[4] = paramTypes[3];
+ Constructor constructor = shadowClassLoaderClass.getDeclaredConstructor(paramTypes);
+ constructor.setAccessible(true);
+ shadowLoader = (ClassLoader) constructor.newInstance(new Object[] {original, "lombok", jarLoc, Arrays.asList(new Object[] {"lombok."}), Arrays.asList(new Object[] {"lombok.patcher.Symbols"})});
+ shadowLoaderField.set(original, shadowLoader);
+ }
+ }
+ }
+
+ if (resolve) {
+ Class[] paramTypes = new Class[2];
+ paramTypes[0] = "".getClass();
+ paramTypes[1] = Boolean.TYPE;
+ Method m = shadowLoader.getClass().getDeclaredMethod("loadClass", new Class[] {String.class, boolean.class});
+ m.setAccessible(true);
+ return (Class) m.invoke(shadowLoader, new Object[] {name, Boolean.TRUE});
+ } else {
+ return shadowLoader.loadClass(name);
+ }
+ } catch (Exception ex) {
+ Throwable t = ex;
+ 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/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index e14d1367..a6d745b6 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2015 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,18 +23,22 @@ package lombok.eclipse.agent;
import static lombok.patcher.scripts.ScriptBuilder.*;
+import java.io.File;
import java.lang.instrument.Instrumentation;
+import java.net.URLClassLoader;
+import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import lombok.core.Agent;
+import lombok.core.AgentLauncher;
+import lombok.patcher.Filter;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
import lombok.patcher.StackRequest;
import lombok.patcher.TargetMatcher;
-import lombok.patcher.equinox.EquinoxClassLoader;
+import lombok.patcher.TransplantMapper;
import lombok.patcher.scripts.ScriptBuilder;
/**
@@ -44,13 +48,12 @@ import lombok.patcher.scripts.ScriptBuilder;
* classes in this package for more information about which classes are transformed and how they are
* transformed.
*/
-public class EclipsePatcher extends Agent {
+public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
// At some point I'd like the agent to be capable of auto-detecting if its on eclipse or on ecj. This class is a sure sign we're not in ecj but in eclipse. -ReinierZ
@SuppressWarnings("unused")
private static final String ECLIPSE_SIGNATURE_CLASS = "org/eclipse/core/runtime/adaptor/EclipseStarter";
- @Override
- public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception {
+ @Override public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected, Class<?> launchingContext) throws Exception {
String[] args = agentArgs == null ? new String[0] : agentArgs.split(":");
boolean forceEcj = false;
boolean forceEclipse = false;
@@ -69,18 +72,31 @@ public class EclipsePatcher extends Agent {
else if (forceEclipse) ecj = false;
else ecj = injected;
- registerPatchScripts(instrumentation, injected, ecj);
+ registerPatchScripts(instrumentation, injected, ecj, launchingContext);
}
- private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly) {
+ private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses, boolean ecjOnly, Class<?> launchingContext) {
ScriptManager sm = new ScriptManager();
sm.registerTransformer(instrumentation);
- if (!ecjOnly) {
- EquinoxClassLoader.addPrefix("lombok.");
- EquinoxClassLoader.registerScripts(sm);
- }
+ sm.setFilter(new Filter() {
+ @Override public boolean shouldTransform(ClassLoader loader, String className, Class<?> classBeingDefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
+ if (!(loader instanceof URLClassLoader)) return true;
+ ClassLoader parent = loader.getParent();
+ if (parent == null) return true;
+ return !parent.getClass().getName().startsWith("org.eclipse.jdt.apt.core.internal.AnnotationProcessorFactoryLoader");
+ }
+ });
+
+ final boolean forceBaseResourceNames = shouldForceBaseResourceNames();
+ sm.setTransplantMapper(new TransplantMapper() {
+ public String mapResourceName(int classFileFormatVersion, String resourceName) {
+ if (classFileFormatVersion < 50 || forceBaseResourceNames) return resourceName;
+ return "Class50/" + resourceName;
+ }
+ });
if (!ecjOnly) {
+ EclipseLoaderPatcher.patchEquinoxLoaders(sm, launchingContext);
patchCatchReparse(sm);
patchIdentifierEndReparse(sm);
patchRetrieveEllipsisStartPosition(sm);
@@ -90,7 +106,7 @@ public class EclipsePatcher extends Agent {
patchHideGeneratedNodes(sm);
patchPostCompileHookEclipse(sm);
patchFixSourceTypeConverter(sm);
- patchDisableLombokForCodeFormatterAndCleanup(sm);
+ patchDisableLombokForCodeCleanup(sm);
patchListRewriteHandleGeneratedMethods(sm);
patchSyntaxAndOccurrencesHighlighting(sm);
patchSortMembersOperation(sm);
@@ -105,16 +121,43 @@ public class EclipsePatcher extends Agent {
patchLombokizeAST(sm);
patchEcjTransformers(sm, ecjOnly);
patchExtensionMethod(sm, ecjOnly);
+ patchRenameField(sm);
if (reloadExistingClasses) sm.reloadClasses(instrumentation);
}
+ private static boolean shouldForceBaseResourceNames() {
+ String shadowOverride = System.getProperty("shadow.override.lombok", "");
+ if (shadowOverride == null || shadowOverride.length() == 0) return false;
+ for (String part : shadowOverride.split("\\s*" + (File.pathSeparatorChar == ';' ? ";" : ":") + "\\s*")) {
+ if (part.equalsIgnoreCase("lombok.jar")) return false;
+ }
+ return true;
+ }
+
+ private static void patchRenameField(ScriptManager sm) {
+ /* RefactoringSearchEngine.search will not return results when renaming field and Data Annotation is present. Return a fake Element to make checks pass */
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor", "checkAccessorDeclarations", "org.eclipse.ltk.core.refactoring.RefactoringStatus", "org.eclipse.core.runtime.IProgressMonitor", "org.eclipse.jdt.core.IMethod"))
+ .methodToWrap(new Hook("org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine", "search", "org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup[]", "org.eclipse.jdt.core.search.SearchPattern","org.eclipse.jdt.core.search.IJavaSearchScope","org.eclipse.core.runtime.IProgressMonitor","org.eclipse.ltk.core.refactoring.RefactoringStatus"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "createFakeSearchResult", "org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup[]", "org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup[]", "java.lang.Object"))
+ .requestExtra(StackRequest.THIS)
+ .transplant().build());
+
+ /* Filter search results which are Generated and based on Fields, e.g. Generated getters/setters */
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor", "addAccessorOccurrences", "void", "org.eclipse.core.runtime.IProgressMonitor", "org.eclipse.jdt.core.IMethod", "java.lang.String","java.lang.String","org.eclipse.ltk.core.refactoring.RefactoringStatus"))
+ .methodToWrap(new Hook("org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup", "getSearchResults", "org.eclipse.jdt.core.search.SearchMatch[]"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGenerated", "org.eclipse.jdt.core.search.SearchMatch[]", "org.eclipse.jdt.core.search.SearchMatch[]"))
+ .transplant().build());
+ }
+
private static void patchExtractInterface(ScriptManager sm) {
/* Fix sourceEnding for generated nodes to avoid null pointer */
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.SourceElementNotifier", "notifySourceElementRequestor", "void", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "org.eclipse.jdt.internal.compiler.ast.ImportReference"))
.methodToWrap(new Hook("org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt", "get", "int", "java.lang.Object"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "getSourceEndFixed", "int", "int", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getSourceEndFixed", "int", "int", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.requestExtra(StackRequest.PARAM1)
.transplant().build());
@@ -127,7 +170,7 @@ public class EclipsePatcher extends Agent {
"org.eclipse.jdt.core.dom.MethodDeclaration"
))
.methodToWrap(new Hook("org.eclipse.jface.text.IDocument", "get", "java.lang.String", "int", "int"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "getRealMethodDeclarationSource", "java.lang.String", "java.lang.String", "java.lang.Object", "org.eclipse.jdt.core.dom.MethodDeclaration"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealMethodDeclarationSource", "java.lang.String", "java.lang.String", "java.lang.Object", "org.eclipse.jdt.core.dom.MethodDeclaration"))
.requestExtra(StackRequest.THIS, StackRequest.PARAM4)
.transplant().build());
@@ -136,20 +179,20 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor", "createMemberDeclarations"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor", "createMethodComments"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil", "getMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit"))
- .replacementMethod(new Hook("lombok.eclipse.agent.PatchFixes", "getRealMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getRealMethodDeclarationNode", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.IMethod", "org.eclipse.jdt.core.dom.CompilationUnit"))
.transplant().build());
/* Do not add @Override's for generated methods */
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.core.dom.rewrite.ListRewrite", "insertFirst"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "isListRewriteOnGeneratedNode", "boolean", "org.eclipse.jdt.core.dom.rewrite.ListRewrite"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isListRewriteOnGeneratedNode", "boolean", "org.eclipse.jdt.core.dom.rewrite.ListRewrite"))
.request(StackRequest.THIS)
.transplant().build());
/* Do not add comments for generated methods */
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.structure.ExtractInterfaceProcessor", "createMethodComment"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
.request(StackRequest.PARAM2)
.transplant().build());
}
@@ -162,7 +205,7 @@ public class EclipsePatcher extends Agent {
*/
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.core.internal.runtime.Product", "getProperty", "java.lang.String", "java.lang.String"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "addLombokNotesToEclipseAboutDialog", "java.lang.String", "java.lang.String", "java.lang.String"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$LombokDeps", "addLombokNotesToEclipseAboutDialog", "java.lang.String", "java.lang.String", "java.lang.String"))
.request(StackRequest.RETURN_VALUE, StackRequest.PARAM1)
.transplant().build());
}
@@ -175,19 +218,13 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.internal.ui.search.OccurrencesFinder", "addUsage"))
.target(new MethodTarget("org.eclipse.jdt.internal.ui.search.OccurrencesFinder", "addWrite"))
.target(new MethodTarget("org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingReconciler$PositionCollector", "visit", "boolean", "org.eclipse.jdt.core.dom.SimpleName"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
- .valueMethod(new Hook("lombok.eclipse.agent.PatchFixes", "returnFalse", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
+ .valueMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "returnFalse", "boolean", "java.lang.Object"))
.request(StackRequest.PARAM1)
.build());
}
- private static void patchDisableLombokForCodeFormatterAndCleanup(ScriptManager sm) {
- sm.addScript(ScriptBuilder.setSymbolDuringMethodCall()
- .target(new MethodTarget("org.eclipse.jdt.internal.formatter.DefaultCodeFormatter", "formatCompilationUnit"))
- .callToWrap(new Hook("org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil", "parseCompilationUnit", "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", "char[]", "java.util.Map", "boolean"))
- .symbol("lombok.disable")
- .build());
-
+ private static void patchDisableLombokForCodeCleanup(ScriptManager sm) {
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.fix.ControlStatementsFix$ControlStatementFinder", "visit", "boolean", "org.eclipse.jdt.core.dom.DoStatement"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.fix.ControlStatementsFix$ControlStatementFinder", "visit", "boolean", "org.eclipse.jdt.core.dom.EnhancedForStatement"))
@@ -201,9 +238,9 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.internal.corext.fix.CodeStyleFix$CodeStyleVisitor", "visit", "boolean", "org.eclipse.jdt.core.dom.QualifiedName"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.fix.CodeStyleFix$CodeStyleVisitor", "visit", "boolean", "org.eclipse.jdt.core.dom.SimpleName"))
// if a generated node has children we can just ignore them as well;
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
.request(StackRequest.PARAM1)
- .valueMethod(new Hook("lombok.eclipse.agent.PatchFixes", "returnFalse", "boolean", "java.lang.Object"))
+ .valueMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "returnFalse", "boolean", "java.lang.Object"))
.build());
}
@@ -211,7 +248,7 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer$ListRewriter", "rewriteList"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent", "getChildren", "org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent[]"))
- .replacementMethod(new Hook("lombok.eclipse.agent.PatchFixes", "listRewriteHandleGeneratedMethods", "org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent[]", "org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "listRewriteHandleGeneratedMethods", "org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent[]", "org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent"))
.build());
}
@@ -223,37 +260,37 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.CompilationUnit"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.CompilationUnit", "types", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.AnnotationTypeDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.AnnotationTypeDeclaration", "bodyDeclarations", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.AnonymousClassDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.AnonymousClassDeclaration", "bodyDeclarations", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.TypeDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.TypeDeclaration", "bodyDeclarations", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.EnumDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.EnumDeclaration", "bodyDeclarations", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.SortElementsOperation$2", "visit", "boolean", "org.eclipse.jdt.core.dom.EnumDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.EnumDeclaration", "enumConstants", "java.util.List"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedNodes", "java.util.List", "java.util.List"))
.transplant().build());
}
@@ -261,7 +298,7 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer", "visit"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner", "getTokenEndOffset", "int", "int", "int"))
- .replacementMethod(new Hook("lombok.eclipse.agent.PatchFixes", "getTokenEndOffsetFixed", "int", "org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner", "int", "int", "java.lang.Object"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "getTokenEndOffsetFixed", "int", "org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner", "int", "int", "java.lang.Object"))
.requestExtra(StackRequest.PARAM1)
.transplant()
.build());
@@ -273,7 +310,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder", "writeClassFileContents"))
.target(new MethodTarget("org.eclipse.jdt.internal.core.builder.AbstractImageBuilder", "writeClassFileContents"))
.methodToWrap(new Hook("org.eclipse.jdt.internal.compiler.ClassFile", "getBytes", "byte[]"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "runPostCompiler", "byte[]", "byte[]", "java.lang.String"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$LombokDeps", "runPostCompiler", "byte[]", "byte[]", "java.lang.String"))
.requestExtra(StackRequest.PARAM3)
.build());
}
@@ -282,24 +319,22 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.tool.EclipseCompilerImpl", "outputClassFiles"))
.methodToWrap(new Hook("javax.tools.JavaFileObject", "openOutputStream", "java.io.OutputStream"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "runPostCompiler", "java.io.OutputStream", "java.io.OutputStream"))
- .transplant()
- .build());
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$LombokDeps", "runPostCompiler", "java.io.OutputStream", "java.io.OutputStream"))
+ .transplant().build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.util.Util", "writeToDisk"))
.methodToWrap(new Hook("java.io.BufferedOutputStream", "<init>", "void", "java.io.OutputStream", "int"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "runPostCompiler", "java.io.BufferedOutputStream", "java.io.BufferedOutputStream", "java.lang.String", "java.lang.String"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$LombokDeps", "runPostCompiler", "java.io.BufferedOutputStream", "java.io.BufferedOutputStream", "java.lang.String", "java.lang.String"))
.requestExtra(StackRequest.PARAM2, StackRequest.PARAM3)
- .transplant()
- .build());
+ .transplant().build());
}
private static void patchHideGeneratedNodes(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder", "findByNode"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder", "findByBinding"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedSimpleNames", "org.eclipse.jdt.core.dom.SimpleName[]",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedSimpleNames", "org.eclipse.jdt.core.dom.SimpleName[]",
"org.eclipse.jdt.core.dom.SimpleName[]"))
.request(StackRequest.RETURN_VALUE).build());
@@ -308,33 +343,41 @@ public class EclipsePatcher extends Agent {
}
private static void patchFormatters(ScriptManager sm) {
+ // before Eclipse Mars
sm.addScript(ScriptBuilder.setSymbolDuringMethodCall()
- .target(new MethodTarget("org.eclipse.jdt.internal.ui.text.java.JavaFormattingStrategy", "format", "void"))
- .callToWrap(new Hook("org.eclipse.jdt.internal.corext.util.CodeFormatterUtil", "reformat", "org.eclipse.text.edits.TextEdit",
- "int", "java.lang.String", "int", "int", "int", "java.lang.String", "java.util.Map"))
- .symbol("lombok.disable").build());
+ .target(new MethodTarget("org.eclipse.jdt.internal.formatter.DefaultCodeFormatter", "formatCompilationUnit"))
+ .callToWrap(new Hook("org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil", "parseCompilationUnit", "org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", "char[]", "java.util.Map", "boolean"))
+ .symbol("lombok.disable")
+ .build());
+
+ // Eclipse Mars and beyond
+ sm.addScript(ScriptBuilder.setSymbolDuringMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.formatter.DefaultCodeFormatter", "parseSourceCode"))
+ .callToWrap(new Hook("org.eclipse.jdt.core.dom.ASTParser", "createAST", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.core.runtime.IProgressMonitor"))
+ .symbol("lombok.disable")
+ .build());
}
private static void patchRefactorScripts(ScriptManager sm) {
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.core.dom.rewrite.ASTRewrite", "replace"))
.target(new MethodTarget("org.eclipse.jdt.core.dom.rewrite.ASTRewrite", "remove"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "skipRewritingGeneratedNodes", "boolean",
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "skipRewritingGeneratedNodes", "boolean",
"org.eclipse.jdt.core.dom.ASTNode"))
.transplant().request(StackRequest.PARAM1).build());
sm.addScript(ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor", "addConstructorRenames"))
.methodToWrap(new Hook("org.eclipse.jdt.core.IType", "getMethods", "org.eclipse.jdt.core.IMethod[]"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "removeGeneratedMethods", "org.eclipse.jdt.core.IMethod[]",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "removeGeneratedMethods", "org.eclipse.jdt.core.IMethod[]",
"org.eclipse.jdt.core.IMethod[]"))
.transplant().build());
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.rename.TempOccurrenceAnalyzer", "visit", "boolean", "org.eclipse.jdt.core.dom.SimpleName"))
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.rename.RenameAnalyzeUtil$ProblemNodeFinder$NameNodeVisitor", "visit", "boolean", "org.eclipse.jdt.core.dom.SimpleName"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
- .valueMethod(new Hook("lombok.eclipse.agent.PatchFixes", "returnTrue", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.core.dom.ASTNode"))
+ .valueMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "returnTrue", "boolean", "java.lang.Object"))
.request(StackRequest.PARAM1)
.transplant().build());
}
@@ -342,30 +385,54 @@ public class EclipsePatcher extends Agent {
private static void patchCatchReparse(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveStartingCatchPosition"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "fixRetrieveStartingCatchPosition", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveStartingCatchPosition", "int", "int", "int"))
.transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM1).build());
}
private static void patchIdentifierEndReparse(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveIdentifierEndPosition"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "fixRetrieveIdentifierEndPosition", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveIdentifierEndPosition", "int", "int", "int"))
.transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build());
}
private static void patchRetrieveEllipsisStartPosition(ScriptManager sm) {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveEllipsisStartPosition"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "fixRetrieveEllipsisStartPosition", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveEllipsisStartPosition", "int", "int", "int"))
.transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build());
}
private static void patchRetrieveRightBraceOrSemiColonPosition(ScriptManager sm) {
- sm.addScript(ScriptBuilder.wrapReturnValue()
- .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBraceOrSemiColonPosition"))
- .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBrace"))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "fixRetrieveRightBraceOrSemiColonPosition", "int", "int", "int"))
- .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build());
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBraceOrSemiColonPosition", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveRightBraceOrSemiColonPosition", "int", "int", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
+ .requestExtra(StackRequest.PARAM2)
+ .transplant()
+ .build());
+
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBrace", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveRightBraceOrSemiColonPosition", "int", "int", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
+ .requestExtra(StackRequest.PARAM2)
+ .transplant()
+ .build());
+
+ sm.addScript(ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.FieldDeclaration"))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBrace", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveRightBraceOrSemiColonPosition", "int", "int", "org.eclipse.jdt.internal.compiler.ast.FieldDeclaration"))
+ .requestExtra(StackRequest.PARAM1)
+ .transplant()
+ .build());
+
+// sm.addScript(ScriptBuilder.wrapReturnValue()
+// .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBraceOrSemiColonPosition"))
+// .target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "retrieveRightBrace"))
+// .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "fixRetrieveRightBraceOrSemiColonPosition", "int", "int", "int"))
+// .transplant().request(StackRequest.RETURN_VALUE, StackRequest.PARAM2).build());
}
private static void patchSetGeneratedFlag(ScriptManager sm) {
@@ -396,14 +463,14 @@ public class EclipsePatcher extends Agent {
return Collections.singleton("org.eclipse.jdt.core.dom.ASTConverter");
}
}).request(StackRequest.PARAM1, StackRequest.RETURN_VALUE)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlag", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void",
"org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.transplant().build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
.request(StackRequest.PARAM2, StackRequest.RETURN_VALUE)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlag", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void",
"org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.transplant().build());
@@ -421,7 +488,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convertToVariableDeclarationStatement", "org.eclipse.jdt.core.dom.VariableDeclarationStatement", "org.eclipse.jdt.internal.compiler.ast.LocalDeclaration"))
/* Targets above are only patched because the resulting dom nodes should be marked if generated. */
.request(StackRequest.PARAM1, StackRequest.RETURN_VALUE)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlag", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlag", "void",
"org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.transplant().build());
@@ -443,7 +510,7 @@ public class EclipsePatcher extends Agent {
}
}).methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM1)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
@@ -451,7 +518,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "convert", "org.eclipse.jdt.core.dom.ASTNode", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM2)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
@@ -460,7 +527,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setQualifiedNameNameAndSourceRanges", "org.eclipse.jdt.core.dom.QualifiedName", "char[][]", "long[]", "int", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM4)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
@@ -468,7 +535,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setQualifiedNameNameAndSourceRanges", "org.eclipse.jdt.core.dom.QualifiedName", "char[][]", "long[]", "int", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.QualifiedName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM4)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
@@ -476,7 +543,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setQualifiedNameNameAndSourceRanges", "org.eclipse.jdt.core.dom.QualifiedName", "char[][]", "long[]", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.SimpleName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM3)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
@@ -484,7 +551,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget("org.eclipse.jdt.core.dom.ASTConverter", "setQualifiedNameNameAndSourceRanges", "org.eclipse.jdt.core.dom.QualifiedName", "char[][]", "long[]", "org.eclipse.jdt.internal.compiler.ast.ASTNode"))
.methodToWrap(new Hook("org.eclipse.jdt.core.dom.QualifiedName", "<init>", "void", "org.eclipse.jdt.core.dom.AST"))
.requestExtra(StackRequest.PARAM3)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "setIsGeneratedFlagForName", "void",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "setIsGeneratedFlagForName", "void",
"org.eclipse.jdt.core.dom.Name", "java.lang.Object"))
.transplant().build());
}
@@ -495,7 +562,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget(PARSER_SIG, "parse", "void",
"org.eclipse.jdt.internal.compiler.ast.MethodDeclaration",
"org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
.transplant()
.request(StackRequest.PARAM1).build());
@@ -503,7 +570,7 @@ public class EclipsePatcher extends Agent {
.target(new MethodTarget(PARSER_SIG, "parse", "void",
"org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration",
"org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration", "boolean"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
.transplant()
.request(StackRequest.PARAM1).build());
@@ -512,7 +579,7 @@ public class EclipsePatcher extends Agent {
"org.eclipse.jdt.internal.compiler.ast.Initializer",
"org.eclipse.jdt.internal.compiler.ast.TypeDeclaration",
"org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration"))
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "checkBit24", "boolean", "java.lang.Object"))
.transplant()
.request(StackRequest.PARAM1).build());
}
@@ -528,12 +595,12 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(PARSER_SIG, "getMethodBodies", "void", CUD_SIG))
- .wrapMethod(new Hook("lombok.eclipse.TransformEclipseAST", "transform", "void", PARSER_SIG, CUD_SIG))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Transform", "transform", "void", PARSER_SIG, CUD_SIG))
.request(StackRequest.THIS, StackRequest.PARAM1).build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(PARSER_SIG, "endParse", CUD_SIG, "int"))
- .wrapMethod(new Hook("lombok.eclipse.TransformEclipseAST", "transform_swapped", "void", CUD_SIG, PARSER_SIG))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Transform", "transform_swapped", "void", CUD_SIG, PARSER_SIG))
.request(StackRequest.THIS, StackRequest.RETURN_VALUE).build());
}
@@ -549,7 +616,7 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget(CLASSSCOPE_SIG, "buildFieldsAndMethods", "void"))
.request(StackRequest.THIS)
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchDelegatePortal", "handleDelegateForType", "boolean", "java.lang.Object"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "handleDelegateForType", "boolean", "java.lang.Object"))
.build());
}
@@ -579,24 +646,24 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(PARSER_SIG, "consumeExitVariableWithInitialization", "void"))
.request(StackRequest.THIS)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchValEclipsePortal", "copyInitializationOfLocalDeclaration", "void", "java.lang.Object"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$ValPortal", "copyInitializationOfLocalDeclaration", "void", "java.lang.Object"))
.build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(PARSER_SIG, "consumeEnhancedForStatementHeader", "void"))
.request(StackRequest.THIS)
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchValEclipsePortal", "copyInitializationOfForEachIterable", "void", "java.lang.Object"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$ValPortal", "copyInitializationOfForEachIterable", "void", "java.lang.Object"))
.build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(ASTCONVERTER_SIG, "setModifiers", "void", VARIABLEDECLARATIONSTATEMENT_SIG, LOCALDECLARATION_SIG))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchValEclipsePortal", "addFinalAndValAnnotationToVariableDeclarationStatement",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$ValPortal", "addFinalAndValAnnotationToVariableDeclarationStatement",
"void", "java.lang.Object", "java.lang.Object", "java.lang.Object"))
.request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build());
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(ASTCONVERTER_SIG, "setModifiers", "void", SINGLEVARIABLEDECLARATION_SIG, LOCALDECLARATION_SIG))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchValEclipsePortal", "addFinalAndValAnnotationToSingleVariableDeclaration",
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$ValPortal", "addFinalAndValAnnotationToSingleVariableDeclaration",
"void", "java.lang.Object", "java.lang.Object", "java.lang.Object"))
.request(StackRequest.THIS, StackRequest.PARAM1, StackRequest.PARAM2).build());
}
@@ -611,26 +678,26 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG))
.request(StackRequest.THIS, StackRequest.PARAM1)
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchVal", "handleValForLocalDeclaration", "boolean", LOCALDECLARATION_SIG, BLOCKSCOPE_SIG))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Val", "handleValForLocalDeclaration", "boolean", LOCALDECLARATION_SIG, BLOCKSCOPE_SIG))
.build());
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget(LOCALDECLARATION_SIG, "resolve", "void", BLOCKSCOPE_SIG))
.methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG))
.requestExtra(StackRequest.THIS)
- .replacementMethod(new Hook("lombok.eclipse.agent.PatchVal", "skipResolveInitializerIfAlreadyCalled2", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG, LOCALDECLARATION_SIG))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Val", "skipResolveInitializerIfAlreadyCalled2", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG, LOCALDECLARATION_SIG))
.build());
sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget(FOREACHSTATEMENT_SIG, "resolve", "void", BLOCKSCOPE_SIG))
.methodToReplace(new Hook(EXPRESSION_SIG, "resolveType", TYPEBINDING_SIG, BLOCKSCOPE_SIG))
- .replacementMethod(new Hook("lombok.eclipse.agent.PatchVal", "skipResolveInitializerIfAlreadyCalled", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Val", "skipResolveInitializerIfAlreadyCalled", TYPEBINDING_SIG, EXPRESSION_SIG, BLOCKSCOPE_SIG))
.build());
sm.addScript(ScriptBuilder.exitEarly()
.target(new MethodTarget(FOREACHSTATEMENT_SIG, "resolve", "void", BLOCKSCOPE_SIG))
.request(StackRequest.THIS, StackRequest.PARAM1)
- .decisionMethod(new Hook("lombok.eclipse.agent.PatchVal", "handleValForForEach", "boolean", FOREACHSTATEMENT_SIG, BLOCKSCOPE_SIG))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Val", "handleValForForEach", "boolean", FOREACHSTATEMENT_SIG, BLOCKSCOPE_SIG))
.build());
}
@@ -641,7 +708,7 @@ public class EclipsePatcher extends Agent {
sm.addScript(ScriptBuilder.wrapReturnValue()
.target(new MethodTarget(SOURCE_TYPE_CONVERTER_SIG, "convertAnnotations", ANNOTATION_SIG + "[]", I_ANNOTATABLE_SIG))
- .wrapMethod(new Hook("lombok.eclipse.agent.PatchFixes", "convertAnnotations", ANNOTATION_SIG + "[]", ANNOTATION_SIG + "[]", I_ANNOTATABLE_SIG))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "convertAnnotations", ANNOTATION_SIG + "[]", ANNOTATION_SIG + "[]", I_ANNOTATABLE_SIG))
.request(StackRequest.PARAM1, StackRequest.RETURN_VALUE).build());
}
@@ -659,10 +726,11 @@ public class EclipsePatcher extends Agent {
}
private static void patchExtensionMethod(ScriptManager sm, boolean ecj) {
- final String PATCH_EXTENSIONMETHOD = "lombok.eclipse.agent.PatchExtensionMethod";
+ final String PATCH_EXTENSIONMETHOD = "lombok.launch.PatchFixesHider$ExtensionMethod";
final String PATCH_EXTENSIONMETHOD_COMPLETIONPROPOSAL_PORTAL = "lombok.eclipse.agent.PatchExtensionMethodCompletionProposalPortal";
final String MESSAGE_SEND_SIG = "org.eclipse.jdt.internal.compiler.ast.MessageSend";
final String TYPE_BINDING_SIG = "org.eclipse.jdt.internal.compiler.lookup.TypeBinding";
+ final String SCOPE_SIG = "org.eclipse.jdt.internal.compiler.lookup.Scope";
final String BLOCK_SCOPE_SIG = "org.eclipse.jdt.internal.compiler.lookup.BlockScope";
final String TYPE_BINDINGS_SIG = "org.eclipse.jdt.internal.compiler.lookup.TypeBinding[]";
final String PROBLEM_REPORTER_SIG = "org.eclipse.jdt.internal.compiler.problem.ProblemReporter";
@@ -690,6 +758,13 @@ public class EclipsePatcher extends Agent {
.replacementMethod(new Hook(PATCH_EXTENSIONMETHOD, "invalidMethod", "void", PROBLEM_REPORTER_SIG, MESSAGE_SEND_SIG, METHOD_BINDING_SIG))
.build());
+ // Since eclipse mars; they added a param.
+ sm.addScript(replaceMethodCall()
+ .target(new MethodTarget(MESSAGE_SEND_SIG, "resolveType", TYPE_BINDING_SIG, BLOCK_SCOPE_SIG))
+ .methodToReplace(new Hook(PROBLEM_REPORTER_SIG, "invalidMethod", "void", MESSAGE_SEND_SIG, METHOD_BINDING_SIG, SCOPE_SIG))
+ .replacementMethod(new Hook(PATCH_EXTENSIONMETHOD, "invalidMethod", "void", PROBLEM_REPORTER_SIG, MESSAGE_SEND_SIG, METHOD_BINDING_SIG, SCOPE_SIG))
+ .build());
+
if (!ecj) {
sm.addScript(wrapReturnValue()
.target(new MethodTarget(COMPLETION_PROPOSAL_COLLECTOR_SIG, "getJavaCompletionProposals", I_JAVA_COMPLETION_PROPOSAL_SIG))
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index b1f5a43a..02760e35 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -699,7 +699,10 @@ public class PatchDelegate {
}
private static void addAllMethodBindings0(List<BindingTuple> list, TypeBinding binding, Set<String> banList, char[] fieldName, ASTNode responsible) throws DelegateRecursion {
- if (binding instanceof SourceTypeBinding) ((SourceTypeBinding) binding).scope.environment().globalOptions.storeAnnotations = true;
+ if (binding instanceof SourceTypeBinding) {
+ ClassScope scope = ((SourceTypeBinding) binding).scope;
+ if (scope != null) scope.environment().globalOptions.storeAnnotations = true;
+ }
if (binding == null) return;
TypeBinding inner;
@@ -721,42 +724,44 @@ public class PatchDelegate {
}
}
- if (binding instanceof ReferenceBinding) {
- ReferenceBinding rb = (ReferenceBinding) binding;
- MethodBinding[] availableMethods = rb.availableMethods();
- FieldBinding[] availableFields = rb.availableFields();
- failIfContainsAnnotation(binding, availableMethods);
- failIfContainsAnnotation(binding, availableFields);
-
- MethodBinding[] parameterizedSigs = availableMethods;
- MethodBinding[] baseSigs = parameterizedSigs;
- if (binding instanceof ParameterizedTypeBinding) {
- baseSigs = ((ParameterizedTypeBinding)binding).genericType().availableMethods();
- if (baseSigs.length != parameterizedSigs.length) {
- // The last known state of eclipse source says this can't happen, so we rely on it,
- // but if this invariant is broken, better to go with 'arg0' naming instead of crashing.
- baseSigs = parameterizedSigs;
- }
- }
- for (int i = 0; i < parameterizedSigs.length; i++) {
- MethodBinding mb = parameterizedSigs[i];
- String sig = printSig(mb);
- if (mb.isStatic()) continue;
- if (mb.isBridge()) continue;
- if (mb.isConstructor()) continue;
- if (mb.isDefaultAbstract()) continue;
- if (!mb.isPublic()) continue;
- if (mb.isSynthetic()) continue;
- if (!banList.add(sig)) continue; // If add returns false, it was already in there.
- BindingTuple pair = new BindingTuple(mb, baseSigs[i], fieldName, responsible);
- list.add(pair);
- }
- addAllMethodBindings0(list, rb.superclass(), banList, fieldName, responsible);
- ReferenceBinding[] interfaces = rb.superInterfaces();
- if (interfaces != null) {
- for (ReferenceBinding iface : interfaces) addAllMethodBindings0(list, iface, banList, fieldName, responsible);
+ if (!(binding instanceof ReferenceBinding)) {
+ return;
+ }
+
+ ReferenceBinding rb = (ReferenceBinding) binding;
+ MethodBinding[] availableMethods = rb.availableMethods();
+ FieldBinding[] availableFields = rb.availableFields();
+ failIfContainsAnnotation(binding, availableMethods);
+ failIfContainsAnnotation(binding, availableFields);
+
+ MethodBinding[] parameterizedSigs = availableMethods;
+ MethodBinding[] baseSigs = parameterizedSigs;
+ if (binding instanceof ParameterizedTypeBinding) {
+ baseSigs = ((ParameterizedTypeBinding)binding).genericType().availableMethods();
+ if (baseSigs.length != parameterizedSigs.length) {
+ // The last known state of eclipse source says this can't happen, so we rely on it,
+ // but if this invariant is broken, better to go with 'arg0' naming instead of crashing.
+ baseSigs = parameterizedSigs;
}
}
+ for (int i = 0; i < parameterizedSigs.length; i++) {
+ MethodBinding mb = parameterizedSigs[i];
+ String sig = printSig(mb);
+ if (mb.isStatic()) continue;
+ if (mb.isBridge()) continue;
+ if (mb.isConstructor()) continue;
+ if (mb.isDefaultAbstract()) continue;
+ if (!mb.isPublic()) continue;
+ if (mb.isSynthetic()) continue;
+ if (!banList.add(sig)) continue; // If add returns false, it was already in there.
+ BindingTuple pair = new BindingTuple(mb, baseSigs[i], fieldName, responsible);
+ list.add(pair);
+ }
+ addAllMethodBindings0(list, rb.superclass(), banList, fieldName, responsible);
+ ReferenceBinding[] interfaces = rb.superInterfaces();
+ if (interfaces != null) {
+ for (ReferenceBinding iface : interfaces) addAllMethodBindings0(list, iface, banList, fieldName, responsible);
+ }
}
private static final char[] STRING_LOMBOK = new char[] {'l', 'o', 'm', 'b', 'o', 'k'};
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
index 8eec27fb..5d586dff 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
@@ -24,6 +24,8 @@ package lombok.eclipse.agent;
import static lombok.eclipse.handlers.EclipseHandlerUtil.createAnnotation;
import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -56,6 +58,7 @@ import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -89,16 +92,47 @@ public class PatchExtensionMethod {
private final ProblemReporter problemReporter;
private final WeakReference<MessageSend> messageSendRef;
private final MethodBinding method;
+ private final Scope scope;
- PostponedInvalidMethodError(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method) {
+ 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 Method getMethod(String name, Class<?>... types) {
+ try {
+ Method m = ProblemReporter.class.getMethod(name, types);
+ m.setAccessible(true);
+ return m;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ PostponedInvalidMethodError(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method, Scope scope) {
this.problemReporter = problemReporter;
this.messageSendRef = new WeakReference<MessageSend>(messageSend);
this.method = method;
+ this.scope = scope;
+ }
+
+ 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);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getCause();
+ if (t instanceof Error) throw (Error) t;
+ if (t instanceof RuntimeException) throw (RuntimeException) t;
+ throw new RuntimeException(t);
+ }
+ }
}
public void fire() {
MessageSend messageSend = messageSendRef.get();
- if (messageSend != null) problemReporter.invalidMethod(messageSend, method);
+ invoke(problemReporter, messageSend, method, scope);
}
}
@@ -185,7 +219,11 @@ public class PatchExtensionMethod {
}
public static void invalidMethod(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method) {
- MessageSend_postponedErrors.set(messageSend, new PostponedInvalidMethodError(problemReporter, messageSend, method));
+ MessageSend_postponedErrors.set(messageSend, new PostponedInvalidMethodError(problemReporter, messageSend, method, null));
+ }
+
+ public static void invalidMethod(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method, Scope scope) {
+ MessageSend_postponedErrors.set(messageSend, new PostponedInvalidMethodError(problemReporter, messageSend, method, scope));
}
public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend methodCall, BlockScope scope) {
@@ -224,12 +262,16 @@ public class PatchExtensionMethod {
if (methodCall.arguments != null) arguments.addAll(Arrays.asList(methodCall.arguments));
List<TypeBinding> argumentTypes = new ArrayList<TypeBinding>();
for (Expression argument : arguments) {
- argumentTypes.add(argument.resolvedType);
+ if (argument.resolvedType != null) argumentTypes.add(argument.resolvedType);
+ // TODO: Instead of just skipping nulls entirely, there is probably a 'unresolved type' placeholder. THAT is what we ought to be adding here!
}
+ Expression[] originalArgs = methodCall.arguments;
+ methodCall.arguments = arguments.toArray(new Expression[0]);
MethodBinding fixedBinding = scope.getMethod(extensionMethod.declaringClass, methodCall.selector, argumentTypes.toArray(new TypeBinding[0]), methodCall);
if (fixedBinding instanceof ProblemMethodBinding) {
+ methodCall.arguments = originalArgs;
if (fixedBinding.declaringClass != null) {
- scope.problemReporter().invalidMethod(methodCall, fixedBinding);
+ PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope);
}
} else {
for (int i = 0, iend = arguments.size(); i < iend; i++) {
@@ -246,7 +288,6 @@ public class PatchExtensionMethod {
arg.implicitConversion = TypeIds.UNBOXING | (id + (id << 4)); // magic see TypeIds
}
}
- methodCall.arguments = arguments.toArray(new Expression[0]);
methodCall.receiver = createNameRef(extensionMethod.declaringClass, methodCall);
methodCall.actualReceiverType = extensionMethod.declaringClass;
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
index 97ca5a7e..c11a49cd 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposal.java
@@ -60,8 +60,6 @@ import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
public class PatchExtensionMethodCompletionProposal {
-
-
public static IJavaCompletionProposal[] getJavaCompletionProposals(IJavaCompletionProposal[] javaCompletionProposals,
CompletionProposalCollector completionProposalCollector) {
@@ -178,7 +176,7 @@ public class PatchExtensionMethodCompletionProposal {
return !proposals.isEmpty() && Reflection.isComplete();
}
- private static int getReplacementOffset(IJavaCompletionProposal proposal) {
+ private static int getReplacementOffset(Object proposal) {
try {
return Reflection.replacementOffsetField.getInt(proposal);
} catch (Exception ignore) {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposalPortal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposalPortal.java
index 6dca1901..19e1952e 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposalPortal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethodCompletionProposalPortal.java
@@ -33,7 +33,6 @@ public class PatchExtensionMethodCompletionProposalPortal {
private static final String COMPLETION_PROPOSAL_COLLECTOR = "org.eclipse.jdt.ui.text.java.CompletionProposalCollector";
private static final String I_JAVA_COMPLETION_PROPOSAL_ARRAY = "[Lorg.eclipse.jdt.ui.text.java.IJavaCompletionProposal;";
-
public static IJavaCompletionProposal[] getJavaCompletionProposals(Object[] javaCompletionProposals, Object completionProposalCollector) {
try {
return (IJavaCompletionProposal[]) ReflectionForUi.getJavaCompletionProposals.invoke(null, javaCompletionProposals, completionProposalCollector);
@@ -52,7 +51,7 @@ public class PatchExtensionMethodCompletionProposalPortal {
}
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
//do anything useful here.
- return (IJavaCompletionProposal[])javaCompletionProposals;
+ return (IJavaCompletionProposal[]) javaCompletionProposals;
}
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java b/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java
deleted file mode 100644
index d1c668a0..00000000
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchFixes.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2010-2013 The Project Lombok Authors.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package lombok.eclipse.agent;
-
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-import lombok.core.DiagnosticsReceiver;
-import lombok.core.PostCompiler;
-import lombok.core.Version;
-import lombok.eclipse.EclipseAugments;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.IAnnotatable;
-import org.eclipse.jdt.core.IAnnotation;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
-import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
-import org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner;
-import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
-
-public class PatchFixes {
- public static String addLombokNotesToEclipseAboutDialog(String origReturnValue, String key) {
- if ("aboutText".equals(key)) {
- return origReturnValue + "\n\nLombok " + Version.getFullVersion() + " is installed. http://projectlombok.org/";
- }
-
- return origReturnValue;
- }
-
- public static boolean isGenerated(org.eclipse.jdt.core.dom.ASTNode node) {
- boolean result = false;
- try {
- result = ((Boolean)node.getClass().getField("$isGenerated").get(node)).booleanValue();
- if (!result && node.getParent() != null && node.getParent() instanceof org.eclipse.jdt.core.dom.QualifiedName)
- result = isGenerated(node.getParent());
- } catch (Exception e) {
- // better to assume it isn't generated
- }
- return result;
- }
-
- public static boolean isListRewriteOnGeneratedNode(org.eclipse.jdt.core.dom.rewrite.ListRewrite rewrite) {
- return isGenerated(rewrite.getParent());
- }
-
- public static boolean returnFalse(java.lang.Object object) {
- return false;
- }
-
- public static boolean returnTrue(java.lang.Object object) {
- return true;
- }
-
- @java.lang.SuppressWarnings({"unchecked", "rawtypes"}) public static java.util.List removeGeneratedNodes(java.util.List list) {
- try {
- java.util.List realNodes = new java.util.ArrayList(list.size());
- for (java.lang.Object node : list) {
- if(!isGenerated(((org.eclipse.jdt.core.dom.ASTNode)node))) {
- realNodes.add(node);
- }
- }
- return realNodes;
- } catch (Exception e) {
- }
- return list;
- }
-
- public static java.lang.String getRealMethodDeclarationSource(java.lang.String original, Object processor, org.eclipse.jdt.core.dom.MethodDeclaration declaration) throws Exception {
- if (!isGenerated(declaration)) return original;
-
- List<org.eclipse.jdt.core.dom.Annotation> annotations = new ArrayList<org.eclipse.jdt.core.dom.Annotation>();
- for (Object modifier : declaration.modifiers()) {
- if (modifier instanceof org.eclipse.jdt.core.dom.Annotation) {
- org.eclipse.jdt.core.dom.Annotation annotation = (org.eclipse.jdt.core.dom.Annotation)modifier;
- String qualifiedAnnotationName = annotation.resolveTypeBinding().getQualifiedName();
- if (!"java.lang.Override".equals(qualifiedAnnotationName) && !"java.lang.SuppressWarnings".equals(qualifiedAnnotationName)) annotations.add(annotation);
- }
- }
-
- StringBuilder signature = new StringBuilder();
- addAnnotations(annotations, signature);
-
- if ((Boolean)processor.getClass().getDeclaredField("fPublic").get(processor)) signature.append("public ");
- if ((Boolean)processor.getClass().getDeclaredField("fAbstract").get(processor)) signature.append("abstract ");
-
- signature
- .append(declaration.getReturnType2().toString())
- .append(" ").append(declaration.getName().getFullyQualifiedName())
- .append("(");
-
- boolean first = true;
- for (Object parameter : declaration.parameters()) {
- if (!first) signature.append(", ");
- first = false;
- // We should also add the annotations of the parameters
- signature.append(parameter);
- }
-
- signature.append(");");
- return signature.toString();
- }
-
- // part of getRealMethodDeclarationSource(...)
- public static void addAnnotations(List<org.eclipse.jdt.core.dom.Annotation> annotations, StringBuilder signature) {
- /*
- * We SHOULD be able to handle the following cases:
- * @Override
- * @Override()
- * @SuppressWarnings("all")
- * @SuppressWarnings({"all", "unused"})
- * @SuppressWarnings(value = "all")
- * @SuppressWarnings(value = {"all", "unused"})
- * @EqualsAndHashCode(callSuper=true, of="id")
- *
- * Currently, we only seem to correctly support:
- * @Override
- * @Override() N.B. We lose the parentheses here, since there are no values. No big deal.
- * @SuppressWarnings("all")
- */
- for (org.eclipse.jdt.core.dom.Annotation annotation : annotations) {
- List<String> values = new ArrayList<String>();
- if (annotation.isSingleMemberAnnotation()) {
- org.eclipse.jdt.core.dom.SingleMemberAnnotation smAnn = (org.eclipse.jdt.core.dom.SingleMemberAnnotation) annotation;
- values.add(smAnn.getValue().toString());
- } else if (annotation.isNormalAnnotation()) {
- org.eclipse.jdt.core.dom.NormalAnnotation normalAnn = (org.eclipse.jdt.core.dom.NormalAnnotation) annotation;
- for (Object value : normalAnn.values()) values.add(value.toString());
- }
-
- signature.append("@").append(annotation.resolveTypeBinding().getQualifiedName());
- if (!values.isEmpty()) {
- signature.append("(");
- boolean first = true;
- for (String string : values) {
- if (!first) signature.append(", ");
- first = false;
- signature.append('"').append(string).append('"');
- }
- signature.append(")");
- }
- signature.append(" ");
- }
- }
-
- public static org.eclipse.jdt.core.dom.MethodDeclaration getRealMethodDeclarationNode(org.eclipse.jdt.core.IMethod sourceMethod, org.eclipse.jdt.core.dom.CompilationUnit cuUnit) throws JavaModelException {
- MethodDeclaration methodDeclarationNode = ASTNodeSearchUtil.getMethodDeclarationNode(sourceMethod, cuUnit);
- if (isGenerated(methodDeclarationNode)) {
- IType declaringType = sourceMethod.getDeclaringType();
- Stack<IType> typeStack = new Stack<IType>();
- while (declaringType != null) {
- typeStack.push(declaringType);
- declaringType = declaringType.getDeclaringType();
- }
-
- IType rootType = typeStack.pop();
- org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = findTypeDeclaration(rootType, cuUnit.types());
- while (!typeStack.isEmpty() && typeDeclaration != null) {
- typeDeclaration = findTypeDeclaration(typeStack.pop(), typeDeclaration.bodyDeclarations());
- }
-
- if (typeStack.isEmpty() && typeDeclaration != null) {
- String methodName = sourceMethod.getElementName();
- for (Object declaration : typeDeclaration.bodyDeclarations()) {
- if (declaration instanceof org.eclipse.jdt.core.dom.MethodDeclaration) {
- org.eclipse.jdt.core.dom.MethodDeclaration methodDeclaration = (org.eclipse.jdt.core.dom.MethodDeclaration) declaration;
- if (methodDeclaration.getName().toString().equals(methodName)) {
- return methodDeclaration;
- }
- }
- }
- }
- }
- return methodDeclarationNode;
- }
-
- // part of getRealMethodDeclarationNode
- public static org.eclipse.jdt.core.dom.AbstractTypeDeclaration findTypeDeclaration(IType searchType, List<?> nodes) {
- for (Object object : nodes) {
- if (object instanceof org.eclipse.jdt.core.dom.AbstractTypeDeclaration) {
- org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = (org.eclipse.jdt.core.dom.AbstractTypeDeclaration) object;
- if (typeDeclaration.getName().toString().equals(searchType.getElementName()))
- return typeDeclaration;
- }
- }
- return null;
- }
-
- public static int getSourceEndFixed(int sourceEnd, org.eclipse.jdt.internal.compiler.ast.ASTNode node) throws Exception {
- if (sourceEnd == -1) {
- org.eclipse.jdt.internal.compiler.ast.ASTNode object = (org.eclipse.jdt.internal.compiler.ast.ASTNode)node.getClass().getField("$generatedBy").get(node);
- if (object != null) {
- return object.sourceEnd;
- }
- }
- return sourceEnd;
- }
-
- public static int fixRetrieveStartingCatchPosition(int original, int start) {
- return original == -1 ? start : original;
- }
-
- public static int fixRetrieveIdentifierEndPosition(int original, int end) {
- return original == -1 ? end : original;
- }
-
- public static int fixRetrieveEllipsisStartPosition(int original, int end) {
- return original == -1 ? end : original;
- }
-
- public static int fixRetrieveRightBraceOrSemiColonPosition(int original, int end) {
-// return original;
- return original == -1 ? end : original; // Need to fix: see issue 325.
- }
-
- public static final int ALREADY_PROCESSED_FLAG = 0x800000; //Bit 24
-
- public static boolean checkBit24(Object node) throws Exception {
- int bits = (Integer)(node.getClass().getField("bits").get(node));
- return (bits & ALREADY_PROCESSED_FLAG) != 0;
- }
-
- public static boolean skipRewritingGeneratedNodes(org.eclipse.jdt.core.dom.ASTNode node) throws Exception {
- return ((Boolean)node.getClass().getField("$isGenerated").get(node)).booleanValue();
- }
-
- public static void setIsGeneratedFlag(org.eclipse.jdt.core.dom.ASTNode domNode,
- org.eclipse.jdt.internal.compiler.ast.ASTNode internalNode) throws Exception {
- if (internalNode == null || domNode == null) return;
- boolean isGenerated = EclipseAugments.ASTNode_generatedBy.get(internalNode) != null;
- if (isGenerated) domNode.getClass().getField("$isGenerated").set(domNode, true);
- }
-
- public static void setIsGeneratedFlagForName(org.eclipse.jdt.core.dom.Name name, Object internalNode) throws Exception {
- if (internalNode instanceof org.eclipse.jdt.internal.compiler.ast.ASTNode) {
- if (EclipseAugments.ASTNode_generatedBy.get((org.eclipse.jdt.internal.compiler.ast.ASTNode) internalNode) != null) {
- name.getClass().getField("$isGenerated").set(name, true);
- }
- }
- }
-
- public static RewriteEvent[] listRewriteHandleGeneratedMethods(RewriteEvent parent) {
- RewriteEvent[] children = parent.getChildren();
- List<RewriteEvent> newChildren = new ArrayList<RewriteEvent>();
- List<RewriteEvent> modifiedChildren = new ArrayList<RewriteEvent>();
- for (int i=0; i<children.length; i++) {
- RewriteEvent child = children[i];
- boolean isGenerated = isGenerated( (org.eclipse.jdt.core.dom.ASTNode)child.getOriginalValue() );
- if (isGenerated) {
- if ((child.getChangeKind() == RewriteEvent.REPLACED || child.getChangeKind() == RewriteEvent.REMOVED)
- && child.getOriginalValue() instanceof org.eclipse.jdt.core.dom.MethodDeclaration
- && child.getNewValue() != null
- ) {
- modifiedChildren.add(new NodeRewriteEvent(null, child.getNewValue()));
- }
- } else {
- newChildren.add(child);
- }
- }
- // Since Eclipse doesn't honor the "insert at specified location" for already existing members,
- // we'll just add them last
- newChildren.addAll(modifiedChildren);
- return newChildren.toArray(new RewriteEvent[newChildren.size()]);
- }
-
- public static int getTokenEndOffsetFixed(TokenScanner scanner, int token, int startOffset, Object domNode) throws CoreException {
- boolean isGenerated = false;
- try {
- isGenerated = (Boolean) domNode.getClass().getField("$isGenerated").get(domNode);
- } catch (Exception e) {
- // If this fails, better to break some refactor scripts than to crash eclipse.
- }
- if (isGenerated) return -1;
- return scanner.getTokenEndOffset(token, startOffset);
- }
-
- public static IMethod[] removeGeneratedMethods(IMethod[] methods) throws Exception {
- List<IMethod> result = new ArrayList<IMethod>();
- for (IMethod m : methods) {
- if (m.getNameRange().getLength() > 0 && !m.getNameRange().equals(m.getSourceRange())) result.add(m);
- }
- return result.size() == methods.length ? methods : result.toArray(new IMethod[result.size()]);
- }
-
- public static SimpleName[] removeGeneratedSimpleNames(SimpleName[] in) throws Exception {
- Field f = SimpleName.class.getField("$isGenerated");
-
- int count = 0;
- for (int i = 0; i < in.length; i++) {
- if (in[i] == null || !((Boolean)f.get(in[i])).booleanValue()) count++;
- }
- if (count == in.length) return in;
- SimpleName[] newSimpleNames = new SimpleName[count];
- count = 0;
- for (int i = 0; i < in.length; i++) {
- if (in[i] == null || !((Boolean)f.get(in[i])).booleanValue()) newSimpleNames[count++] = in[i];
- }
- return newSimpleNames;
- }
-
- public static byte[] runPostCompiler(byte[] bytes, String fileName) {
- byte[] transformed = PostCompiler.applyTransformations(bytes, fileName, DiagnosticsReceiver.CONSOLE);
- return transformed == null ? bytes : transformed;
- }
-
- public static OutputStream runPostCompiler(OutputStream out) throws IOException {
- return PostCompiler.wrapOutputStream(out, "TEST", DiagnosticsReceiver.CONSOLE);
- }
-
- public static BufferedOutputStream runPostCompiler(BufferedOutputStream out, String path, String name) throws IOException {
- String fileName = path + "/" + name;
- return new BufferedOutputStream(PostCompiler.wrapOutputStream(out, fileName, DiagnosticsReceiver.CONSOLE));
- }
-
- public static Annotation[] convertAnnotations(Annotation[] out, IAnnotatable annotatable) {
- IAnnotation[] in;
-
- try {
- in = annotatable.getAnnotations();
- } catch (Exception e) {
- return out;
- }
-
- if (out == null) return null;
- int toWrite = 0;
-
- for (int idx = 0; idx < out.length; idx++) {
- String oName = new String(out[idx].type.getLastToken());
- boolean found = false;
- for (IAnnotation i : in) {
- String name = i.getElementName();
- int li = name.lastIndexOf('.');
- if (li > -1) name = name.substring(li + 1);
- if (name.equals(oName)) {
- found = true;
- break;
- }
- }
- if (!found) out[idx] = null;
- else toWrite++;
- }
-
- Annotation[] replace = out;
- if (toWrite < out.length) {
- replace = new Annotation[toWrite];
- int idx = 0;
- for (int i = 0; i < out.length; i++) {
- if (out[i] == null) continue;
- replace[idx++] = out[i];
- }
- }
-
- return replace;
- }
-}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java b/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java
new file mode 100644
index 00000000..52f63765
--- /dev/null
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchFixesShadowLoaded.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.agent;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import lombok.core.DiagnosticsReceiver;
+import lombok.core.PostCompiler;
+import lombok.core.Version;
+
+public class PatchFixesShadowLoaded {
+ public static String addLombokNotesToEclipseAboutDialog(String origReturnValue, String key) {
+ if ("aboutText".equals(key)) {
+ return origReturnValue + "\n\nLombok " + Version.getFullVersion() + " is installed. https://projectlombok.org/";
+ }
+ return origReturnValue;
+ }
+
+ public static byte[] runPostCompiler(byte[] bytes, String fileName) {
+ byte[] transformed = PostCompiler.applyTransformations(bytes, fileName, DiagnosticsReceiver.CONSOLE);
+ return transformed == null ? bytes : transformed;
+ }
+
+ public static OutputStream runPostCompiler(OutputStream out) throws IOException {
+ return PostCompiler.wrapOutputStream(out, "TEST", DiagnosticsReceiver.CONSOLE);
+ }
+
+ public static BufferedOutputStream runPostCompiler(BufferedOutputStream out, String path, String name) throws IOException {
+ String fileName = path + "/" + name;
+ return new BufferedOutputStream(PostCompiler.wrapOutputStream(out, fileName, DiagnosticsReceiver.CONSOLE));
+ }
+}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index e734dceb..3da37869 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 The Project Lombok Authors.
+ * Copyright (C) 2010-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,11 +21,6 @@
*/
package lombok.eclipse.agent;
-import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
-import static lombok.eclipse.Eclipse.*;
-
-import java.lang.reflect.Field;
-
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
@@ -43,6 +38,11 @@ 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 java.lang.reflect.Field;
+
+import static lombok.eclipse.Eclipse.poss;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType;
+
public class PatchVal {
// This is half of the work for 'val' support - the other half is in PatchValEclipse. This half is enough for ecj.
@@ -57,6 +57,9 @@ public class PatchVal {
return expr.resolveType(scope);
} catch (NullPointerException e) {
return null;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // This will occur internally due to for example 'val x = mth("X");', where mth takes 2 arguments.
+ return null;
}
}
@@ -66,6 +69,9 @@ public class PatchVal {
return expr.resolveType(scope);
} catch (NullPointerException e) {
return null;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // This will occur internally due to for example 'val x = mth("X");', where mth takes 2 arguments.
+ return null;
}
}
@@ -78,31 +84,44 @@ public class PatchVal {
return true;
}
- public static boolean couldBeVal(TypeReference ref) {
+ public static boolean couldBe(String key, TypeReference ref) {
+ String[] keyParts = key.split("\\.");
if (ref instanceof SingleTypeReference) {
char[] token = ((SingleTypeReference)ref).token;
- return matches("val", token);
+ return matches(keyParts[keyParts.length - 1], token);
}
if (ref instanceof QualifiedTypeReference) {
char[][] tokens = ((QualifiedTypeReference)ref).tokens;
- if (tokens == null || tokens.length != 2) return false;
- return matches("lombok", tokens[0]) && matches("val", tokens[1]);
+ if (keyParts.length != tokens.length) return false;
+ for(int i = 0; i < tokens.length; ++i) {
+ String part = keyParts[i];
+ char[] token = tokens[i];
+ if (!matches(part, token)) return false;
+ }
+ return true;
}
return false;
}
-
- private static boolean isVal(TypeReference ref, BlockScope scope) {
- if (!couldBeVal(ref)) return false;
-
+
+ private static boolean is(TypeReference ref, BlockScope scope, String key) {
+ if (!couldBe(key, ref)) return false;
+
TypeBinding resolvedType = ref.resolvedType;
if (resolvedType == null) resolvedType = ref.resolveType(scope, false);
if (resolvedType == null) return false;
char[] pkg = resolvedType.qualifiedPackageName();
char[] nm = resolvedType.qualifiedSourceName();
- return matches("lombok", pkg) && matches("val", nm);
+ int pkgFullLength = pkg.length > 0 ? pkg.length + 1: 0;
+ char[] fullName = new char[pkgFullLength + nm.length];
+ if(pkg.length > 0) {
+ System.arraycopy(pkg, 0, fullName, 0, pkg.length);
+ fullName[pkg.length] = '.';
+ }
+ System.arraycopy(nm, 0, fullName, pkgFullLength, nm.length);
+ return matches(key, fullName);
}
public static final class Reflection {
@@ -126,9 +145,20 @@ public class PatchVal {
if (local == null || !LocalDeclaration.class.equals(local.getClass())) return false;
boolean decomponent = false;
- if (!isVal(local.type, scope)) return false;
+ boolean val = isVal(local, scope);
+ boolean var = isVar(local, scope);
+ if (!(val || var)) return false;
- if (new Throwable().getStackTrace()[2].getClassName().contains("ForStatement")) return false;
+ StackTraceElement[] st = new Throwable().getStackTrace();
+ for (int i = 0; i < st.length - 2 && i < 10; i++) {
+ if (st[i].getClassName().equals("lombok.launch.PatchFixesHider$Val")) {
+ boolean valInForStatement = val &&
+ st[i + 1].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.LocalDeclaration") &&
+ st[i + 2].getClassName().equals("org.eclipse.jdt.internal.compiler.ast.ForStatement");
+ if (valInForStatement) return false;
+ break;
+ }
+ }
Expression init = local.initialization;
if (init == null && Reflection.initCopyField != null) {
@@ -157,7 +187,7 @@ public class PatchVal {
TypeBinding resolved = null;
try {
- resolved = decomponent ? getForEachComponentType(init, scope) : init.resolveType(scope);
+ resolved = decomponent ? getForEachComponentType(init, scope) : resolveForExpression(init, scope);
} catch (NullPointerException e) {
// This definitely occurs if as part of resolving the initializer expression, a
// lambda expression in it must also be resolved (such as when lambdas are part of
@@ -174,23 +204,33 @@ public class PatchVal {
}
}
- local.modifiers |= ClassFileConstants.AccFinal;
+ if(val) local.modifiers |= ClassFileConstants.AccFinal;
local.annotations = addValAnnotation(local.annotations, local.type, scope);
local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
return false;
}
+ private static boolean isVar(LocalDeclaration local, BlockScope scope) {
+ return is(local.type, scope, "lombok.experimental.var") || is(local.type, scope, "lombok.var");
+ }
+
+ private static boolean isVal(LocalDeclaration local, BlockScope scope) {
+ return is(local.type, scope, "lombok.val");
+ }
+
public static boolean handleValForForEach(ForeachStatement forEach, BlockScope scope) {
if (forEach.elementVariable == null) return false;
- if (!isVal(forEach.elementVariable.type, scope)) return false;
+ boolean val = isVal(forEach.elementVariable, scope);
+ boolean var = isVar(forEach.elementVariable, scope);
+ if (!(val || var)) return false;
TypeBinding component = getForEachComponentType(forEach.collection, scope);
if (component == null) return false;
TypeReference replacement = makeType(component, forEach.elementVariable.type, false);
- forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
+ if (val) forEach.elementVariable.modifiers |= ClassFileConstants.AccFinal;
forEach.elementVariable.annotations = addValAnnotation(forEach.elementVariable.annotations, forEach.elementVariable.type, scope);
forEach.elementVariable.type = replacement != null ? replacement :
new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(forEach.elementVariable.type, 3));
@@ -215,7 +255,7 @@ public class PatchVal {
private static TypeBinding getForEachComponentType(Expression collection, BlockScope scope) {
if (collection != null) {
TypeBinding resolved = collection.resolvedType;
- if (resolved == null) resolved = collection.resolveType(scope);
+ if (resolved == null) resolved = resolveForExpression(collection, scope);
if (resolved == null) return null;
if (resolved.isArrayType()) {
resolved = ((ArrayBinding) resolved).elementsType();
@@ -243,4 +283,13 @@ public class PatchVal {
return null;
}
+
+ private static TypeBinding resolveForExpression(Expression collection, BlockScope scope) {
+ try {
+ return collection.resolveType(scope);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Known cause of issues; for example: val e = mth("X"), where mth takes 2 arguments.
+ return null;
+ }
+ }
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
index 7d5f36f4..46237dcf 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 The Project Lombok Authors.
+ * Copyright (C) 2010-2018 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,6 +47,7 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.parser.Parser;
@@ -65,7 +66,9 @@ public class PatchValEclipse {
ForeachStatement foreachDecl = (ForeachStatement) astStack[astPtr];
ASTNode init = foreachDecl.collection;
if (init == null) return;
- if (foreachDecl.elementVariable == null || !PatchVal.couldBeVal(foreachDecl.elementVariable.type)) return;
+ boolean val = couldBeVal(foreachDecl.elementVariable.type);
+ boolean var = couldBeVar(foreachDecl.elementVariable.type);
+ if (foreachDecl.elementVariable == null || !(val || var)) return;
try {
if (Reflection.iterableCopyField != null) Reflection.iterableCopyField.set(foreachDecl.elementVariable, init);
@@ -88,7 +91,9 @@ public class PatchValEclipse {
if (!(variableDecl instanceof LocalDeclaration)) return;
ASTNode init = variableDecl.initialization;
if (init == null) return;
- if (!PatchVal.couldBeVal(variableDecl.type)) return;
+ boolean val = couldBeVal(variableDecl.type);
+ boolean var = couldBeVar(variableDecl.type);
+ if (!(val || var)) return;
try {
if (Reflection.initCopyField != null) Reflection.initCopyField.set(variableDecl, init);
@@ -97,6 +102,10 @@ public class PatchValEclipse {
}
}
+ private static boolean couldBeVar(TypeReference type) {
+ return PatchVal.couldBe("lombok.experimental.var", type) || PatchVal.couldBe("lombok.var", type);
+ }
+
public static void addFinalAndValAnnotationToSingleVariableDeclaration(Object converter, SingleVariableDeclaration out, LocalDeclaration in) {
@SuppressWarnings("unchecked") List<IExtendedModifier> modifiers = out.modifiers();
addFinalAndValAnnotationToModifierList(converter, modifiers, out.getAST(), in);
@@ -115,7 +124,7 @@ public class PatchValEclipse {
Annotation valAnnotation = null;
for (Annotation ann : in.annotations) {
- if (PatchVal.couldBeVal(ann.type)) {
+ if (couldBeVal(ann.type)) {
found = true;
valAnnotation = ann;
break;
@@ -167,6 +176,10 @@ public class PatchValEclipse {
}
}
+ private static boolean couldBeVal(TypeReference type) {
+ return PatchVal.couldBe("lombok.val", type);
+ }
+
public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) {
Modifier modifier = null;
try {
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
new file mode 100644
index 00000000..b1d73352
--- /dev/null
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -0,0 +1,671 @@
+/*
+ * Copyright (C) 2010-2015 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.launch;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import lombok.eclipse.EclipseAugments;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.SourceField;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner;
+import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
+import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
+
+/** These contain a mix of the following:
+ * <ul>
+ * <li> 'dependency free' method wrappers that cross the shadowloader barrier.
+ * <li> methods that directly patch, <em>but</em>, these should ALWAYS be transplanted.
+ * </ul>
+ *
+ * <strong>This class lives on the outside of the shadowloader barrier, and as a consequence, cannot access any other lombok code except other
+ * code in the {@code lombok.launch} package!</strong>.
+ * <p>
+ * This class is package private with lots of public inner static classes. This hides all of them from IDE autocomplete dialogs and such but at the JVM
+ * level the inner static class are just plain public, which is important, because calls to the contents of these inner static classes are injected into
+ * various eclipse classes verbatim, and if they weren't public, the verifier wouldn't accept it.
+ */
+final class PatchFixesHider {
+
+ /** These utility methods are only used 'internally', but because of transplant methods, the class (and its methods) still have to be public! */
+ public static final class Util {
+ private static ClassLoader shadowLoader;
+
+ public static Class<?> shadowLoadClass(String name) {
+ try {
+ if (shadowLoader == null) {
+ try {
+ Class.forName("lombok.core.LombokNode");
+ // If we get here, then lombok is already available.
+ shadowLoader = Util.class.getClassLoader();
+ } catch (ClassNotFoundException e) {
+ // If we get here, it isn't, and we should use the shadowloader.
+ shadowLoader = Main.createShadowClassLoader();
+ }
+ }
+
+ return Class.forName(name, true, shadowLoader);
+ } catch (ClassNotFoundException e) {
+ throw sneakyThrow(e);
+ }
+ }
+
+ public static Method findMethod(Class<?> type, String name, Class<?>... parameterTypes) {
+ try {
+ return type.getDeclaredMethod(name, parameterTypes);
+ } catch (NoSuchMethodException e) {
+ throw sneakyThrow(e);
+ }
+ }
+
+ public static Object invokeMethod(Method method, Object... args) {
+ try {
+ return method.invoke(null, args);
+ } catch (IllegalAccessException e) {
+ throw sneakyThrow(e);
+ } catch (InvocationTargetException e) {
+ throw sneakyThrow(e.getCause());
+ }
+ }
+
+ private static RuntimeException sneakyThrow(Throwable t) {
+ if (t == null) throw new NullPointerException("t");
+ Util.<RuntimeException>sneakyThrow0(t);
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T extends Throwable> void sneakyThrow0(Throwable t) throws T {
+ throw (T)t;
+ }
+ }
+
+ /** Contains patch fixes that are dependent on lombok internals. */
+ public static final class LombokDeps {
+ public static final Method ADD_LOMBOK_NOTES;
+ public static final Method POST_COMPILER_BYTES_STRING;
+ public static final Method POST_COMPILER_OUTPUTSTREAM;
+ public static final Method POST_COMPILER_BUFFEREDOUTPUTSTREAM_STRING_STRING;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchFixesShadowLoaded");
+ ADD_LOMBOK_NOTES = Util.findMethod(shadowed, "addLombokNotesToEclipseAboutDialog", String.class, String.class);
+ POST_COMPILER_BYTES_STRING = Util.findMethod(shadowed, "runPostCompiler", byte[].class, String.class);
+ POST_COMPILER_OUTPUTSTREAM = Util.findMethod(shadowed, "runPostCompiler", OutputStream.class);
+ POST_COMPILER_BUFFEREDOUTPUTSTREAM_STRING_STRING = Util.findMethod(shadowed, "runPostCompiler", BufferedOutputStream.class, String.class, String.class);
+ }
+
+ public static String addLombokNotesToEclipseAboutDialog(String origReturnValue, String key) {
+ return (String) Util.invokeMethod(LombokDeps.ADD_LOMBOK_NOTES, origReturnValue, key);
+ }
+
+ public static byte[] runPostCompiler(byte[] bytes, String fileName) {
+ return (byte[]) Util.invokeMethod(LombokDeps.POST_COMPILER_BYTES_STRING, bytes, fileName);
+ }
+
+ public static OutputStream runPostCompiler(OutputStream out) throws IOException {
+ return (OutputStream) Util.invokeMethod(LombokDeps.POST_COMPILER_OUTPUTSTREAM, out);
+ }
+
+ public static BufferedOutputStream runPostCompiler(BufferedOutputStream out, String path, String name) throws IOException {
+ return (BufferedOutputStream) Util.invokeMethod(LombokDeps.POST_COMPILER_BUFFEREDOUTPUTSTREAM_STRING_STRING, out, path, name);
+ }
+ }
+
+ public static final class Transform {
+ private static final Method TRANSFORM;
+ private static final Method TRANSFORM_SWAPPED;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.TransformEclipseAST");
+ TRANSFORM = Util.findMethod(shadowed, "transform", Parser.class, CompilationUnitDeclaration.class);
+ TRANSFORM_SWAPPED = Util.findMethod(shadowed, "transform_swapped", CompilationUnitDeclaration.class, Parser.class);
+ }
+
+ public static void transform(Parser parser, CompilationUnitDeclaration ast) throws IOException {
+ Util.invokeMethod(TRANSFORM, parser, ast);
+ }
+
+ public static void transform_swapped(CompilationUnitDeclaration ast, Parser parser) throws IOException {
+ Util.invokeMethod(TRANSFORM_SWAPPED, ast, parser);
+ }
+ }
+
+ /** Contains patch code to support {@code @Delegate} */
+ public static final class Delegate {
+ private static final Method HANDLE_DELEGATE_FOR_TYPE;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegatePortal");
+ HANDLE_DELEGATE_FOR_TYPE = Util.findMethod(shadowed, "handleDelegateForType", Object.class);
+ }
+
+ public static boolean handleDelegateForType(Object classScope) {
+ return (Boolean) Util.invokeMethod(HANDLE_DELEGATE_FOR_TYPE, classScope);
+ }
+ }
+
+ /** Contains patch code to support {@code val} (eclipse specific) */
+ public static final class ValPortal {
+ private static final Method COPY_INITIALIZATION_OF_FOR_EACH_ITERABLE;
+ private static final Method COPY_INITIALIZATION_OF_LOCAL_DECLARATION;
+ private static final Method ADD_FINAL_AND_VAL_ANNOTATION_TO_VARIABLE_DECLARATION_STATEMENT;
+ private static final Method ADD_FINAL_AND_VAL_ANNOTATION_TO_SINGLE_VARIABLE_DECLARATION;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchValEclipsePortal");
+ COPY_INITIALIZATION_OF_FOR_EACH_ITERABLE = Util.findMethod(shadowed, "copyInitializationOfForEachIterable", Object.class);
+ COPY_INITIALIZATION_OF_LOCAL_DECLARATION = Util.findMethod(shadowed, "copyInitializationOfLocalDeclaration", Object.class);
+ ADD_FINAL_AND_VAL_ANNOTATION_TO_VARIABLE_DECLARATION_STATEMENT = Util.findMethod(shadowed, "addFinalAndValAnnotationToVariableDeclarationStatement", Object.class, Object.class, Object.class);
+ ADD_FINAL_AND_VAL_ANNOTATION_TO_SINGLE_VARIABLE_DECLARATION = Util.findMethod(shadowed, "addFinalAndValAnnotationToSingleVariableDeclaration", Object.class, Object.class, Object.class);
+ }
+
+ public static void copyInitializationOfForEachIterable(Object parser) {
+ Util.invokeMethod(COPY_INITIALIZATION_OF_FOR_EACH_ITERABLE, parser);
+ }
+
+ public static void copyInitializationOfLocalDeclaration(Object parser) {
+ Util.invokeMethod(COPY_INITIALIZATION_OF_LOCAL_DECLARATION, parser);
+ }
+
+ public static void addFinalAndValAnnotationToVariableDeclarationStatement(Object converter, Object out, Object in) {
+ Util.invokeMethod(ADD_FINAL_AND_VAL_ANNOTATION_TO_VARIABLE_DECLARATION_STATEMENT, converter, out, in);
+ }
+
+ public static void addFinalAndValAnnotationToSingleVariableDeclaration(Object converter, Object out, Object in) {
+ Util.invokeMethod(ADD_FINAL_AND_VAL_ANNOTATION_TO_SINGLE_VARIABLE_DECLARATION, converter, out, in);
+ }
+ }
+
+ /** Contains patch code to support {@code val} (eclipse and ecj) */
+ public static final class Val {
+ private static final Method SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED;
+ private static final Method SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED2;
+ private static final Method HANDLE_VAL_FOR_LOCAL_DECLARATION;
+ private static final Method HANDLE_VAL_FOR_FOR_EACH;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchVal");
+ SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED = Util.findMethod(shadowed, "skipResolveInitializerIfAlreadyCalled", Expression.class, BlockScope.class);
+ SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED2 = Util.findMethod(shadowed, "skipResolveInitializerIfAlreadyCalled2", Expression.class, BlockScope.class, LocalDeclaration.class);
+ HANDLE_VAL_FOR_LOCAL_DECLARATION = Util.findMethod(shadowed, "handleValForLocalDeclaration", LocalDeclaration.class, BlockScope.class);
+ HANDLE_VAL_FOR_FOR_EACH = Util.findMethod(shadowed, "handleValForForEach", ForeachStatement.class, BlockScope.class);
+ }
+
+ public static TypeBinding skipResolveInitializerIfAlreadyCalled(Expression expr, BlockScope scope) {
+ return (TypeBinding) Util.invokeMethod(SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED, expr, scope);
+ }
+
+ public static TypeBinding skipResolveInitializerIfAlreadyCalled2(Expression expr, BlockScope scope, LocalDeclaration decl) {
+ return (TypeBinding) Util.invokeMethod(SKIP_RESOLVE_INITIALIZER_IF_ALREADY_CALLED2, expr, scope, decl);
+ }
+
+ public static boolean handleValForLocalDeclaration(LocalDeclaration local, BlockScope scope) {
+ return (Boolean) Util.invokeMethod(HANDLE_VAL_FOR_LOCAL_DECLARATION, local, scope);
+ }
+
+ public static boolean handleValForForEach(ForeachStatement forEach, BlockScope scope) {
+ return (Boolean) Util.invokeMethod(HANDLE_VAL_FOR_FOR_EACH, forEach, scope);
+ }
+ }
+
+ /** Contains patch code to support {@code @ExtensionMethod} */
+ public static final class ExtensionMethod {
+ private static final Method RESOLVE_TYPE;
+ private static final Method ERROR_NO_METHOD_FOR;
+ private static final Method INVALID_METHOD, INVALID_METHOD2;
+
+ static {
+ Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchExtensionMethod");
+ RESOLVE_TYPE = Util.findMethod(shadowed, "resolveType", TypeBinding.class, MessageSend.class, BlockScope.class);
+ ERROR_NO_METHOD_FOR = Util.findMethod(shadowed, "errorNoMethodFor", ProblemReporter.class, MessageSend.class, TypeBinding.class, TypeBinding[].class);
+ INVALID_METHOD = Util.findMethod(shadowed, "invalidMethod", ProblemReporter.class, MessageSend.class, MethodBinding.class);
+ INVALID_METHOD2 = Util.findMethod(shadowed, "invalidMethod", ProblemReporter.class, MessageSend.class, MethodBinding.class, Scope.class);
+ }
+
+ public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend methodCall, BlockScope scope) {
+ return (TypeBinding) Util.invokeMethod(RESOLVE_TYPE, resolvedType, methodCall, scope);
+ }
+
+ public static void errorNoMethodFor(ProblemReporter problemReporter, MessageSend messageSend, TypeBinding recType, TypeBinding[] params) {
+ Util.invokeMethod(ERROR_NO_METHOD_FOR, problemReporter, messageSend, recType, params);
+ }
+
+ public static void invalidMethod(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method) {
+ Util.invokeMethod(INVALID_METHOD, problemReporter, messageSend, method);
+ }
+
+ public static void invalidMethod(ProblemReporter problemReporter, MessageSend messageSend, MethodBinding method, Scope scope) {
+ Util.invokeMethod(INVALID_METHOD2, problemReporter, messageSend, method, scope);
+ }
+ }
+
+ /**
+ * Contains a mix of methods: ecj only, ecj+eclipse, and eclipse only. As a consequence, _EVERY_ method from here used for ecj MUST be
+ * transplanted, as ecj itself cannot load this class (signatures refer to things that don't exist in ecj-only mode).
+ * <p>
+ * Because of usage of transplant(), a bunch of these contain direct code and don't try to cross the shadowloader barrier.
+ */
+ public static final class PatchFixes {
+ public static boolean isGenerated(org.eclipse.jdt.core.dom.ASTNode node) {
+ boolean result = false;
+ try {
+ result = ((Boolean)node.getClass().getField("$isGenerated").get(node)).booleanValue();
+ if (!result && node.getParent() != null && node.getParent() instanceof org.eclipse.jdt.core.dom.QualifiedName) {
+ result = isGenerated(node.getParent());
+ }
+ } catch (Exception e) {
+ // better to assume it isn't generated
+ }
+ return result;
+ }
+
+ public static boolean isListRewriteOnGeneratedNode(org.eclipse.jdt.core.dom.rewrite.ListRewrite rewrite) {
+ return isGenerated(rewrite.getParent());
+ }
+
+ public static boolean returnFalse(java.lang.Object object) {
+ return false;
+ }
+
+ public static boolean returnTrue(java.lang.Object object) {
+ return true;
+ }
+
+ @java.lang.SuppressWarnings({"unchecked", "rawtypes"}) public static java.util.List removeGeneratedNodes(java.util.List list) {
+ try {
+ java.util.List realNodes = new java.util.ArrayList(list.size());
+ for (java.lang.Object node : list) {
+ if(!isGenerated(((org.eclipse.jdt.core.dom.ASTNode)node))) {
+ realNodes.add(node);
+ }
+ }
+ return realNodes;
+ } catch (Exception e) {
+ }
+ return list;
+ }
+
+ public static java.lang.String getRealMethodDeclarationSource(java.lang.String original, Object processor, org.eclipse.jdt.core.dom.MethodDeclaration declaration) throws Exception {
+ if (!isGenerated(declaration)) return original;
+
+ List<org.eclipse.jdt.core.dom.Annotation> annotations = new ArrayList<org.eclipse.jdt.core.dom.Annotation>();
+ for (Object modifier : declaration.modifiers()) {
+ if (modifier instanceof org.eclipse.jdt.core.dom.Annotation) {
+ org.eclipse.jdt.core.dom.Annotation annotation = (org.eclipse.jdt.core.dom.Annotation)modifier;
+ String qualifiedAnnotationName = annotation.resolveTypeBinding().getQualifiedName();
+ if (!"java.lang.Override".equals(qualifiedAnnotationName) && !"java.lang.SuppressWarnings".equals(qualifiedAnnotationName)) annotations.add(annotation);
+ }
+ }
+
+ StringBuilder signature = new StringBuilder();
+ addAnnotations(annotations, signature);
+
+ if ((Boolean)processor.getClass().getDeclaredField("fPublic").get(processor)) signature.append("public ");
+ if ((Boolean)processor.getClass().getDeclaredField("fAbstract").get(processor)) signature.append("abstract ");
+
+ signature
+ .append(declaration.getReturnType2().toString())
+ .append(" ").append(declaration.getName().getFullyQualifiedName())
+ .append("(");
+
+ boolean first = true;
+ for (Object parameter : declaration.parameters()) {
+ if (!first) signature.append(", ");
+ first = false;
+ // We should also add the annotations of the parameters
+ signature.append(parameter);
+ }
+
+ signature.append(");");
+ return signature.toString();
+ }
+
+ // part of getRealMethodDeclarationSource(...)
+ public static void addAnnotations(List<org.eclipse.jdt.core.dom.Annotation> annotations, StringBuilder signature) {
+ /*
+ * We SHOULD be able to handle the following cases:
+ * @Override
+ * @Override()
+ * @SuppressWarnings("all")
+ * @SuppressWarnings({"all", "unused"})
+ * @SuppressWarnings(value = "all")
+ * @SuppressWarnings(value = {"all", "unused"})
+ * @EqualsAndHashCode(callSuper=true, of="id")
+ *
+ * Currently, we only seem to correctly support:
+ * @Override
+ * @Override() N.B. We lose the parentheses here, since there are no values. No big deal.
+ * @SuppressWarnings("all")
+ */
+ for (org.eclipse.jdt.core.dom.Annotation annotation : annotations) {
+ List<String> values = new ArrayList<String>();
+ if (annotation.isSingleMemberAnnotation()) {
+ org.eclipse.jdt.core.dom.SingleMemberAnnotation smAnn = (org.eclipse.jdt.core.dom.SingleMemberAnnotation) annotation;
+ values.add(smAnn.getValue().toString());
+ } else if (annotation.isNormalAnnotation()) {
+ org.eclipse.jdt.core.dom.NormalAnnotation normalAnn = (org.eclipse.jdt.core.dom.NormalAnnotation) annotation;
+ for (Object value : normalAnn.values()) values.add(value.toString());
+ }
+
+ signature.append("@").append(annotation.resolveTypeBinding().getQualifiedName());
+ if (!values.isEmpty()) {
+ signature.append("(");
+ boolean first = true;
+ for (String string : values) {
+ if (!first) signature.append(", ");
+ first = false;
+ signature.append('"').append(string).append('"');
+ }
+ signature.append(")");
+ }
+ signature.append(" ");
+ }
+ }
+
+ public static org.eclipse.jdt.core.dom.MethodDeclaration getRealMethodDeclarationNode(org.eclipse.jdt.core.IMethod sourceMethod, org.eclipse.jdt.core.dom.CompilationUnit cuUnit) throws JavaModelException {
+ MethodDeclaration methodDeclarationNode = ASTNodeSearchUtil.getMethodDeclarationNode(sourceMethod, cuUnit);
+ if (isGenerated(methodDeclarationNode)) {
+ IType declaringType = sourceMethod.getDeclaringType();
+ Stack<IType> typeStack = new Stack<IType>();
+ while (declaringType != null) {
+ typeStack.push(declaringType);
+ declaringType = declaringType.getDeclaringType();
+ }
+
+ IType rootType = typeStack.pop();
+ org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = findTypeDeclaration(rootType, cuUnit.types());
+ while (!typeStack.isEmpty() && typeDeclaration != null) {
+ typeDeclaration = findTypeDeclaration(typeStack.pop(), typeDeclaration.bodyDeclarations());
+ }
+
+ if (typeStack.isEmpty() && typeDeclaration != null) {
+ String methodName = sourceMethod.getElementName();
+ for (Object declaration : typeDeclaration.bodyDeclarations()) {
+ if (declaration instanceof org.eclipse.jdt.core.dom.MethodDeclaration) {
+ org.eclipse.jdt.core.dom.MethodDeclaration methodDeclaration = (org.eclipse.jdt.core.dom.MethodDeclaration) declaration;
+ if (methodDeclaration.getName().toString().equals(methodName)) {
+ return methodDeclaration;
+ }
+ }
+ }
+ }
+ }
+ return methodDeclarationNode;
+ }
+
+ // part of getRealMethodDeclarationNode
+ public static org.eclipse.jdt.core.dom.AbstractTypeDeclaration findTypeDeclaration(IType searchType, List<?> nodes) {
+ for (Object object : nodes) {
+ if (object instanceof org.eclipse.jdt.core.dom.AbstractTypeDeclaration) {
+ org.eclipse.jdt.core.dom.AbstractTypeDeclaration typeDeclaration = (org.eclipse.jdt.core.dom.AbstractTypeDeclaration) object;
+ if (typeDeclaration.getName().toString().equals(searchType.getElementName()))
+ return typeDeclaration;
+ }
+ }
+ return null;
+ }
+
+ public static int getSourceEndFixed(int sourceEnd, org.eclipse.jdt.internal.compiler.ast.ASTNode node) throws Exception {
+ if (sourceEnd == -1) {
+ org.eclipse.jdt.internal.compiler.ast.ASTNode object = (org.eclipse.jdt.internal.compiler.ast.ASTNode)node.getClass().getField("$generatedBy").get(node);
+ if (object != null) {
+ return object.sourceEnd;
+ }
+ }
+ return sourceEnd;
+ }
+
+ public static int fixRetrieveStartingCatchPosition(int original, int start) {
+ return original == -1 ? start : original;
+ }
+
+ public static int fixRetrieveIdentifierEndPosition(int original, int end) {
+ return original == -1 ? end : original;
+ }
+
+ public static int fixRetrieveEllipsisStartPosition(int original, int end) {
+ return original == -1 ? end : original;
+ }
+
+ public static int fixRetrieveRightBraceOrSemiColonPosition(int original, int end) {
+// if (original == -1) {
+// Thread.dumpStack();
+// }
+ return original == -1 ? end : original;
+ }
+
+ public static int fixRetrieveRightBraceOrSemiColonPosition(int retVal, AbstractMethodDeclaration amd) {
+ if (retVal != -1 || amd == null) return retVal;
+ boolean isGenerated = EclipseAugments.ASTNode_generatedBy.get(amd) != null;
+ if (isGenerated) return amd.declarationSourceEnd;
+ return -1;
+ }
+
+ public static int fixRetrieveRightBraceOrSemiColonPosition(int retVal, FieldDeclaration fd) {
+ if (retVal != -1 || fd == null) return retVal;
+ boolean isGenerated = EclipseAugments.ASTNode_generatedBy.get(fd) != null;
+ if (isGenerated) return fd.declarationSourceEnd;
+ return -1;
+ }
+
+ public static final int ALREADY_PROCESSED_FLAG = 0x800000; //Bit 24
+
+ public static boolean checkBit24(Object node) throws Exception {
+ int bits = (Integer)(node.getClass().getField("bits").get(node));
+ return (bits & ALREADY_PROCESSED_FLAG) != 0;
+ }
+
+ public static boolean skipRewritingGeneratedNodes(org.eclipse.jdt.core.dom.ASTNode node) throws Exception {
+ return ((Boolean) node.getClass().getField("$isGenerated").get(node)).booleanValue();
+ }
+
+ public static void setIsGeneratedFlag(org.eclipse.jdt.core.dom.ASTNode domNode,
+ org.eclipse.jdt.internal.compiler.ast.ASTNode internalNode) throws Exception {
+
+ if (internalNode == null || domNode == null) return;
+ boolean isGenerated = EclipseAugments.ASTNode_generatedBy.get(internalNode) != null;
+ if (isGenerated) domNode.getClass().getField("$isGenerated").set(domNode, true);
+ }
+
+ public static void setIsGeneratedFlagForName(org.eclipse.jdt.core.dom.Name name, Object internalNode) throws Exception {
+ if (internalNode instanceof org.eclipse.jdt.internal.compiler.ast.ASTNode) {
+ boolean isGenerated = EclipseAugments.ASTNode_generatedBy.get((org.eclipse.jdt.internal.compiler.ast.ASTNode) internalNode) != null;
+ if (isGenerated) name.getClass().getField("$isGenerated").set(name, true);
+ }
+ }
+
+ public static RewriteEvent[] listRewriteHandleGeneratedMethods(RewriteEvent parent) {
+ RewriteEvent[] children = parent.getChildren();
+ List<RewriteEvent> newChildren = new ArrayList<RewriteEvent>();
+ List<RewriteEvent> modifiedChildren = new ArrayList<RewriteEvent>();
+ for (int i = 0; i < children.length; i++) {
+ RewriteEvent child = children[i];
+ boolean isGenerated = isGenerated((org.eclipse.jdt.core.dom.ASTNode) child.getOriginalValue());
+ if (isGenerated) {
+ boolean isReplacedOrRemoved = child.getChangeKind() == RewriteEvent.REPLACED || child.getChangeKind() == RewriteEvent.REMOVED;
+ boolean convertingFromMethod = child.getOriginalValue() instanceof org.eclipse.jdt.core.dom.MethodDeclaration;
+ if (isReplacedOrRemoved && convertingFromMethod && child.getNewValue() != null) {
+ modifiedChildren.add(new NodeRewriteEvent(null, child.getNewValue()));
+ }
+ } else {
+ newChildren.add(child);
+ }
+ }
+ // Since Eclipse doesn't honor the "insert at specified location" for already existing members,
+ // we'll just add them last
+ newChildren.addAll(modifiedChildren);
+ return newChildren.toArray(new RewriteEvent[newChildren.size()]);
+ }
+
+ public static int getTokenEndOffsetFixed(TokenScanner scanner, int token, int startOffset, Object domNode) throws CoreException {
+ boolean isGenerated = false;
+ try {
+ isGenerated = (Boolean) domNode.getClass().getField("$isGenerated").get(domNode);
+ } catch (Exception e) {
+ // If this fails, better to break some refactor scripts than to crash eclipse.
+ }
+ if (isGenerated) return -1;
+ return scanner.getTokenEndOffset(token, startOffset);
+ }
+
+ public static IMethod[] removeGeneratedMethods(IMethod[] methods) throws Exception {
+ List<IMethod> result = new ArrayList<IMethod>();
+ for (IMethod m : methods) {
+ if (m.getNameRange().getLength() > 0 && !m.getNameRange().equals(m.getSourceRange())) result.add(m);
+ }
+ return result.size() == methods.length ? methods : result.toArray(new IMethod[result.size()]);
+ }
+
+ public static SearchMatch[] removeGenerated(SearchMatch[] returnValue) {
+ List<SearchMatch> result = new ArrayList<SearchMatch>();
+ for (int j = 0; j < returnValue.length; j++) {
+ SearchMatch searchResult = returnValue[j];
+ if (searchResult.getElement() instanceof IField) {
+ IField field = (IField) searchResult.getElement();
+
+ // can not check for value=lombok because annotation is
+ // not fully resolved
+ IAnnotation annotation = field.getAnnotation("Generated");
+ if (annotation != null) {
+ // Method generated at field location, skip
+ continue;
+ }
+
+ }
+ result.add(searchResult);
+ }
+ return result.toArray(new SearchMatch[result.size()]);
+ }
+
+ public static SearchResultGroup[] createFakeSearchResult(SearchResultGroup[] returnValue,
+ Object/*
+ * org.eclipse.jdt.internal.corext.refactoring.rename.
+ * RenameFieldProcessor
+ */ processor) throws Exception {
+ if (returnValue == null || returnValue.length == 0) {
+ // if no matches were found, check if Data annotation is present on the class
+ Field declaredField = processor.getClass().getDeclaredField("fField");
+ if (declaredField != null) {
+ declaredField.setAccessible(true);
+ SourceField fField = (SourceField) declaredField.get(processor);
+ IAnnotation dataAnnotation = fField.getDeclaringType().getAnnotation("Data");
+ if (dataAnnotation != null) {
+ // add fake item, to make refactoring checks pass
+ return new SearchResultGroup[] {new SearchResultGroup(null, new SearchMatch[1])};
+ }
+ }
+ }
+ return returnValue;
+ }
+
+ public static SimpleName[] removeGeneratedSimpleNames(SimpleName[] in) throws Exception {
+ Field f = SimpleName.class.getField("$isGenerated");
+
+ int count = 0;
+ for (int i = 0; i < in.length; i++) {
+ if (in[i] == null || !((Boolean)f.get(in[i])).booleanValue()) count++;
+ }
+ if (count == in.length) return in;
+ SimpleName[] newSimpleNames = new SimpleName[count];
+ count = 0;
+ for (int i = 0; i < in.length; i++) {
+ if (in[i] == null || !((Boolean)f.get(in[i])).booleanValue()) newSimpleNames[count++] = in[i];
+ }
+ return newSimpleNames;
+ }
+
+ public static Annotation[] convertAnnotations(Annotation[] out, IAnnotatable annotatable) {
+ IAnnotation[] in;
+
+ try {
+ in = annotatable.getAnnotations();
+ } catch (Exception e) {
+ return out;
+ }
+
+ if (out == null) return null;
+ int toWrite = 0;
+
+ for (int idx = 0; idx < out.length; idx++) {
+ String oName = new String(out[idx].type.getLastToken());
+ boolean found = false;
+ for (IAnnotation i : in) {
+ String name = i.getElementName();
+ int li = name.lastIndexOf('.');
+ if (li > -1) name = name.substring(li + 1);
+ if (name.equals(oName)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) out[idx] = null;
+ else toWrite++;
+ }
+
+ Annotation[] replace = out;
+ if (toWrite < out.length) {
+ replace = new Annotation[toWrite];
+ int idx = 0;
+ for (int i = 0; i < out.length; i++) {
+ if (out[i] == null) continue;
+ replace[idx++] = out[i];
+ }
+ }
+
+ return replace;
+ }
+ }
+}