From 3b20b70363fe85f354934fcfb47fdcfd0701a31e Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 12 Mar 2024 22:12:22 +0100 Subject: [PATCH] Support @Delegate in eclipse 2024-03 --- .../lombok/eclipse/agent/EclipsePatcher.java | 7 ++ .../lombok/eclipse/agent/PatchDelegate.java | 14 +++- .../lombok/launch/PatchFixesHider.java | 19 +++++- .../delegate/model/DelegateModel.java | 9 +++ .../src/lombok/eclipse/EclipseTests.java | 3 +- .../src/lombok/eclipse/misc/DelegateTest.java | 66 +++++++++++++++++++ 6 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 test/eclipse/resource/delegate/model/DelegateModel.java create mode 100644 test/eclipse/src/lombok/eclipse/misc/DelegateTest.java diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 12060ffbd8..e3a52ba125 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -771,6 +771,13 @@ private static void addPatchesForDelegate(ScriptManager sm) { .request(StackRequest.RETURN_VALUE, StackRequest.THIS) .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "addGeneratedDelegateMethods", "java.lang.Object[]", "java.lang.Object", "java.lang.Object")) .build()); + + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.core.JavaElement", "getElementInfo", "org.eclipse.jdt.internal.compiler.env.IElementInfo")) + .request(StackRequest.THIS) + .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "isDelegateSourceMethod", "boolean", "java.lang.Object")) + .valueMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "returnElementInfo", "java.lang.Object", "java.lang.Object")) + .build()); } private static void addPatchesForValEclipse(ScriptManager sm) { diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java index d7b1759839..fee6db43cf 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2021 The Project Lombok Authors. + * Copyright (C) 2010-2024 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,10 +21,11 @@ */ package lombok.eclipse.agent; -import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.EcjAugments.*; +import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -726,6 +727,15 @@ public static Object[] addGeneratedDelegateMethods(Object[] returnValue, Object return EclipseOnlyMethods.addGeneratedDelegateMethodsToChildren(returnValue, javaElement); } + public static Object returnElementInfo(Object delegateSourceMethod) { + Field field = Permit.permissiveGetField(delegateSourceMethod.getClass(), "sourceMethodInfo"); + return Permit.permissiveReadField(Object.class, field, delegateSourceMethod); + } + + public static boolean isDelegateSourceMethod(Object sourceMethod) { + return sourceMethod.getClass().getName().equals("lombok.eclipse.agent.PatchDelegate$EclipseOnlyMethods$DelegateSourceMethod"); + } + public static class EclipseOnlyMethods { private static void cleanupDelegateMethods(CompilationUnitDeclaration cud) { CompilationUnit compilationUnit = getCompilationUnit(cud); diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 84a0cf3d8e..7ba663ccf4 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -277,11 +277,16 @@ public static void transform_swapped(Object ast, Object parser) throws IOExcepti public static final class Delegate { private static final Method HANDLE_DELEGATE_FOR_TYPE; private static final Method ADD_GENERATED_DELEGATE_METHODS; + public static final Method IS_DELEGATE_SOURCE_METHOD; + public static final Method RETURN_ELEMENT_INFO; static { - Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegatePortal"); - HANDLE_DELEGATE_FOR_TYPE = Util.findMethod(shadowed, "handleDelegateForType", Object.class); - ADD_GENERATED_DELEGATE_METHODS = Util.findMethod(shadowed, "addGeneratedDelegateMethods", Object.class, Object.class); + Class shadowedPortal = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegatePortal"); + HANDLE_DELEGATE_FOR_TYPE = Util.findMethod(shadowedPortal, "handleDelegateForType", Object.class); + ADD_GENERATED_DELEGATE_METHODS = Util.findMethod(shadowedPortal, "addGeneratedDelegateMethods", Object.class, Object.class); + Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegate"); + IS_DELEGATE_SOURCE_METHOD = Util.findMethod(shadowed, "isDelegateSourceMethod", Object.class); + RETURN_ELEMENT_INFO = Util.findMethod(shadowed, "returnElementInfo", Object.class); } public static boolean handleDelegateForType(Object classScope) { @@ -291,6 +296,14 @@ public static boolean handleDelegateForType(Object classScope) { public static Object[] addGeneratedDelegateMethods(Object returnValue, Object javaElement) { return (Object[]) Util.invokeMethod(ADD_GENERATED_DELEGATE_METHODS, returnValue, javaElement); } + + public static boolean isDelegateSourceMethod(Object sourceMethod) { + return (Boolean) Util.invokeMethod(IS_DELEGATE_SOURCE_METHOD, sourceMethod); + } + + public static Object returnElementInfo(Object delegateSourceMethod) { + return Util.invokeMethod(RETURN_ELEMENT_INFO, delegateSourceMethod); + } } /** Contains patch code to support {@code val} (eclipse specific) */ diff --git a/test/eclipse/resource/delegate/model/DelegateModel.java b/test/eclipse/resource/delegate/model/DelegateModel.java new file mode 100644 index 0000000000..4c1700e952 --- /dev/null +++ b/test/eclipse/resource/delegate/model/DelegateModel.java @@ -0,0 +1,9 @@ +package pkg; + +import lombok.experimental.Delegate; + +public class DelegateModel { + + @Delegate + private Runnable run; +} \ No newline at end of file diff --git a/test/eclipse/src/lombok/eclipse/EclipseTests.java b/test/eclipse/src/lombok/eclipse/EclipseTests.java index e09313dd61..66f5d9faf5 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseTests.java +++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java @@ -28,6 +28,7 @@ import lombok.eclipse.cleanup.CleanupTest; import lombok.eclipse.compile.NoErrorsTest; import lombok.eclipse.edit.SelectTest; +import lombok.eclipse.misc.DelegateTest; import lombok.eclipse.misc.JavadocTest; import lombok.eclipse.refactoring.ExtractInterfaceTest; import lombok.eclipse.refactoring.InlineTest; @@ -35,7 +36,7 @@ import lombok.eclipse.references.FindReferencesTest; @RunWith(Suite.class) -@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class, JavadocTest.class}) +@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class, JavadocTest.class, DelegateTest.class}) public class EclipseTests { } diff --git a/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java b/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java new file mode 100644 index 0000000000..899dc9f941 --- /dev/null +++ b/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2024 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.misc; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.WorkingCopyOwner; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import lombok.eclipse.EclipseRunner; +import lombok.eclipse.SetupSingleFileTest; + +@RunWith(EclipseRunner.class) +public class DelegateTest { + + @Rule + public SetupSingleFileTest setup = new SetupSingleFileTest(); + + @Test + public void model() throws Exception { + ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("DelegateModel.java"); + + WorkingCopyOwner workingCopyOwner = new WorkingCopyOwner() {}; + ICompilationUnit workingCopy = cu.getWorkingCopy(workingCopyOwner, null); + try { + workingCopy.reconcile(ICompilationUnit.NO_AST, true, true, workingCopy.getOwner(), null); + + assertThat(workingCopy.findPrimaryType().getMethods().length, is(not(0))); + + IMethod runMethod = workingCopy.findPrimaryType().getMethods()[0]; + assertEquals(runMethod.getElementName(), "run"); + + ISourceRange sourceRange = runMethod.getSourceRange(); + assertNotNull(sourceRange); + assertEquals(sourceRange.getOffset(), 84); + assertEquals(sourceRange.getLength(), 9); + } finally { + workingCopy.discardWorkingCopy(); + } + } +}