mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 18:18:48 +00:00
[fixes #3440] Prepend jdt.core classloader to the parser classloader
This commit is contained in:
1 parent
f8191d5bae
commit
d6ee06c534
3 files changed
+54
-41
No files matched your search
@@ -109,6 +109,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
|
||||
patchRenameField(sm);
|
||||
patchInline(sm);
|
||||
patchNullCheck(sm);
|
||||
patchCrossModuleClassLoading(sm);
|
||||
|
||||
patchForTests(sm);
|
||||
|
||||
@@ -1032,6 +1033,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
|
||||
.build());
|
||||
}
|
||||
|
||||
private static void patchCrossModuleClassLoading(ScriptManager sm) {
|
||||
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
|
||||
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "<clinit>"))
|
||||
.wrapMethod(new Hook("lombok.launch.PatchFixesHider$ModuleClassLoading", "parserClinit", "void"))
|
||||
.build());
|
||||
}
|
||||
|
||||
private static void patchForTests(ScriptManager sm) {
|
||||
sm.addScriptIfWitness(new String[] {"lombok/eclipse/EclipseRunner"}, ScriptBuilder.wrapReturnValue()
|
||||
.target(new MethodTarget("org.osgi.framework.FrameworkUtil", "getBundle", "org.osgi.framework.Bundle", "java.lang.Class"))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2021 The Project Lombok Authors.
|
||||
* Copyright (C) 2010-2023 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
|
||||
@@ -60,6 +60,7 @@ import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
|
||||
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
|
||||
import org.eclipse.jdt.internal.compiler.parser.Parser;
|
||||
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;
|
||||
@@ -163,6 +164,38 @@ final class PatchFixesHider {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void prependToClassLoader(ClassLoader currentClassLoader, ClassLoader prepend) {
|
||||
try {
|
||||
Method prependParentMethod = Permit.getMethod(currentClassLoader.getClass(), "prependParent", ClassLoader.class);
|
||||
Permit.invoke(prependParentMethod, currentClassLoader, prepend);
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassLoader findJdtCoreClassLoader(ClassLoader classLoader) {
|
||||
try {
|
||||
Method getBundleMethod = Permit.getMethod(classLoader.getClass(), "getBundle");
|
||||
Object bundle = Permit.invoke(getBundleMethod, classLoader);
|
||||
|
||||
Method getBundleContextMethod = Permit.getMethod(bundle.getClass(), "getBundleContext");
|
||||
Object bundleContext = Permit.invoke(getBundleContextMethod, bundle);
|
||||
|
||||
Method getBundlesMethod = Permit.getMethod(bundleContext.getClass(), "getBundles");
|
||||
Object[] bundles = (Object[]) Permit.invoke(getBundlesMethod, bundleContext);
|
||||
|
||||
for (Object searchBundle : bundles) {
|
||||
if (searchBundle.toString().startsWith("org.eclipse.jdt.core_")) {
|
||||
Method getModuleClassLoaderMethod = Permit.getMethod(searchBundle.getClass(), "getModuleClassLoader", boolean.class);
|
||||
return (ClassLoader) Permit.invoke(getModuleClassLoaderMethod, searchBundle, false);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Contains patch fixes that are dependent on lombok internals. */
|
||||
@@ -201,6 +234,14 @@ final class PatchFixesHider {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class ModuleClassLoading {
|
||||
public static void parserClinit() {
|
||||
ClassLoader jdtCoreClassLoader = Util.findJdtCoreClassLoader(Parser.class.getClassLoader());
|
||||
ClassLoader currentClassLoader = ModuleClassLoading.class.getClassLoader();
|
||||
Util.prependToClassLoader(currentClassLoader, jdtCoreClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Transform {
|
||||
private static Method TRANSFORM;
|
||||
private static Method TRANSFORM_SWAPPED;
|
||||
@@ -208,51 +249,14 @@ final class PatchFixesHider {
|
||||
private static synchronized void init(ClassLoader prepend) {
|
||||
if (TRANSFORM != null) return;
|
||||
|
||||
prependClassLoader(prepend);
|
||||
if (!prepend.toString().contains("org.eclipse.jdt.core:")) {
|
||||
ClassLoader jdtCoreClassLoader = findJdtCoreClassLoader(prepend);
|
||||
prependClassLoader(jdtCoreClassLoader);
|
||||
}
|
||||
Main.prependClassLoader(prepend);
|
||||
ClassLoader currentClassLoader = Transform.class.getClassLoader();
|
||||
Util.prependToClassLoader(currentClassLoader, prepend);
|
||||
Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.TransformEclipseAST");
|
||||
TRANSFORM = Util.findMethodAnyArgs(shadowed, "transform");
|
||||
TRANSFORM_SWAPPED = Util.findMethodAnyArgs(shadowed, "transform_swapped");
|
||||
}
|
||||
|
||||
private static void prependClassLoader(ClassLoader classLoader) {
|
||||
Main.prependClassLoader(classLoader);
|
||||
try {
|
||||
ClassLoader currentClassLoader = Transform.class.getClassLoader();
|
||||
|
||||
Method prependParentMethod = Permit.getMethod(currentClassLoader.getClass(), "prependParent", ClassLoader.class);
|
||||
Permit.invoke(prependParentMethod, currentClassLoader, classLoader);
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassLoader findJdtCoreClassLoader(ClassLoader classLoader) {
|
||||
try {
|
||||
Method getBundleMethod = Permit.getMethod(classLoader.getClass(), "getBundle");
|
||||
Object bundle = Permit.invoke(getBundleMethod, classLoader);
|
||||
|
||||
Method getBundleContextMethod = Permit.getMethod(bundle.getClass(), "getBundleContext");
|
||||
Object bundleContext = Permit.invoke(getBundleContextMethod, bundle);
|
||||
|
||||
Method getBundlesMethod = Permit.getMethod(bundleContext.getClass(), "getBundles");
|
||||
Object[] bundles = (Object[]) Permit.invoke(getBundlesMethod, bundleContext);
|
||||
|
||||
for (Object searchBundle : bundles) {
|
||||
if (searchBundle.toString().startsWith("org.eclipse.jdt.core_")) {
|
||||
Method getModuleClassLoaderMethod = Permit.getMethod(searchBundle.getClass(), "getModuleClassLoader", boolean.class);
|
||||
return (ClassLoader) Permit.invoke(getModuleClassLoaderMethod, searchBundle, false);
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void transform(Object parser, Object ast) throws IOException {
|
||||
init(parser.getClass().getClassLoader());
|
||||
Util.invokeMethod(TRANSFORM, parser, ast);
|
||||
|
||||
@@ -112,6 +112,7 @@ class ShadowClassLoader extends ClassLoader {
|
||||
public void prependParent(ClassLoader loader) {
|
||||
if (loader == null) return;
|
||||
if (loader == getParent()) return;
|
||||
if (loader == this) return;
|
||||
prependedParentLoaders.add(loader);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user