Generalized the agent mechanism; now 1 lombok.jar can serve as the agent for BOTH netbeans AND eclipse, and is future-ready for an IntelliJ agent.

This commit is contained in:
Reinier Zwitserloot committed 2009-12-01 13:53:07 +01:00
1 parent 92e2afe9b0
commit 199f7f74fd
5 files changed
+90 -33

No files matched your search

+1 -2
View File
@@ -159,8 +159,7 @@ lombok code including the various agents.
<fileset dir="build" includes="changelog.txt" />
<fileset dir="." includes="LICENCE" />
<manifest>
<!-- <attribute name="Premain-Class" value="lombok.eclipse.agent.EclipsePatcher" /> -->
<attribute name="Premain-Class" value="lombok.netbeans.agent.NetbeansPatcher" />
<attribute name="Premain-Class" value="lombok.core.Agent" />
<attribute name="Can-Redefine-Classes" value="true" />
<attribute name="Main-Class" value="lombok.core.Main" />
<attribute name="Lombok-Version" value="${lombok.version}" />
+62
View File
@@ -0,0 +1,62 @@
/*
* Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
*
* 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.core;
import java.lang.instrument.Instrumentation;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public abstract class Agent {
protected abstract void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception;
public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Exception {
runAgents(agentArgs, instrumentation, true);
}
public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception {
runAgents(agentArgs, instrumentation, false);
}
private static final List<String> AGENT_NAMES = Collections.unmodifiableList(Arrays.asList(
"lombok.netbeans.agent.NetbeansPatcher",
"lombok.eclipse.agent.EclipsePatcher"
));
private static void runAgents(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception {
for (String agentName : AGENT_NAMES) {
try {
Class<?> agentClass = Class.forName(agentName);
Agent agent = (Agent) agentClass.newInstance();
agent.runAgent(agentArgs, instrumentation, injected);
} catch (ClassNotFoundException e) {
//That's okay - this lombok evidently is a version with support for something stripped out.
} catch (ClassCastException e) {
throw new InternalError("Lombok bug. Class: " + agentName + " is not an implementation of lombok.core.Agent");
} catch (IllegalAccessException e) {
throw new InternalError("Lombok bug. Class: " + agentName + " is not public");
} catch (InstantiationException e) {
throw new InternalError("Lombok bug. Class: " + agentName + " is not concrete or has no public no-args constructor");
}
}
}
}
@@ -26,6 +26,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import lombok.core.Agent;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
@@ -41,15 +42,10 @@ 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 {
private EclipsePatcher() {}
public static void agentmain(@SuppressWarnings("unused") String agentArgs, Instrumentation instrumentation) throws Exception {
registerPatchScripts(instrumentation, true);
}
public static void premain(@SuppressWarnings("unused") String agentArgs, Instrumentation instrumentation) throws Exception {
registerPatchScripts(instrumentation, false);
public class EclipsePatcher extends Agent {
@Override
public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception {
registerPatchScripts(instrumentation, injected);
}
private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses) {
@@ -23,29 +23,29 @@ package lombok.netbeans.agent;
import java.lang.instrument.Instrumentation;
import lombok.core.Agent;
import lombok.patcher.Hook;
import lombok.patcher.MethodTarget;
import lombok.patcher.ScriptManager;
import lombok.patcher.StackRequest;
import lombok.patcher.equinox.EquinoxClassLoader;
import lombok.patcher.scripts.ScriptBuilder;
public class NetbeansPatcher {
private NetbeansPatcher() {}
public static void agentmain(@SuppressWarnings("unused") String agentArgs, Instrumentation instrumentation) throws Exception {
registerPatchScripts(instrumentation, true);
}
public static void premain(@SuppressWarnings("unused") String agentArgs, Instrumentation instrumentation) throws Exception {
registerPatchScripts(instrumentation, false);
/**
* This is a java-agent that patches some of netbeans's classes so that lombok is initialized as Javac TaskListener,
* allowing us to change AST nodes anytime netbeans parses source code. It also fixes some of the places in netbeans that
* can't deal with generated code.
*
* The hard work on figuring out where to patch has been done by Jan Lahoda (jlahoda@netbeans.org)
*/
public class NetbeansPatcher extends Agent {
@Override
public void runAgent(String agentArgs, Instrumentation instrumentation, boolean injected) throws Exception {
registerPatchScripts(instrumentation, injected);
}
private static void registerPatchScripts(Instrumentation instrumentation, boolean reloadExistingClasses) {
ScriptManager sm = new ScriptManager();
sm.registerTransformer(instrumentation);
EquinoxClassLoader.addPrefix("lombok.");
EquinoxClassLoader.registerScripts(sm);
patchNetbeansJavac(sm);
patchNetbeansMissingPositionAwareness(sm);
@@ -48,16 +48,16 @@ public class PatchFixes {
if (context.get(TaskListener.class) != null)
context.put(TaskListener.class, (TaskListener)null);
if (taskListener != null) {
// try {
// Method m = JavacTaskImpl.class.getDeclaredMethod("wrap", TaskListener.class);
// try {
// m.setAccessible(true);
// } catch (SecurityException ignore) {}
// TaskListener w = (TaskListener)m.invoke(that, taskListener);
context.put(TaskListener.class, taskListener);
// } catch (InvocationTargetException e) {
// throw e.getCause();
// }
try {
Method m = JavacTaskImpl.class.getDeclaredMethod("wrap", TaskListener.class);
try {
m.setAccessible(true);
} catch (SecurityException ignore) {}
TaskListener w = (TaskListener)m.invoke(that, taskListener);
context.put(TaskListener.class, w);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}