From 1b66450566b04567c6c6dfd7a68585ebd427fe49 Mon Sep 17 00:00:00 2001 From: mjaggard Date: Fri, 1 Dec 2023 11:06:31 +0000 Subject: [PATCH 01/65] Explain builder default gotchas --- website/templates/features/Builder.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html index 1461161f..b7a4f2e2 100644 --- a/website/templates/features/Builder.html +++ b/website/templates/features/Builder.html @@ -66,7 +66,7 @@

Now that the "method" mode is clear, putting a @Builder annotation on a constructor functions similarly; effectively, constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their type parameters are the same as the type parameters of the class itself.

- Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself. If you do have an explicit constructor, put the @Builder annotation on the constructor instead of on the class. Note that if you put both `@Value` and `@Builder` on a class, the package-private constructor that `@Builder` wants to generate 'wins' and suppresses the constructor that `@Value` wants to make. + Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself or created one with @NoArgsConstructor. If you do have an explicit constructor, put the @Builder annotation on the constructor instead of on the class. Note that if you put both `@Value` and `@Builder` on a class, the package-private constructor that `@Builder` wants to generate 'wins' and suppresses the constructor that `@Value` wants to make.

If using @Builder to generate builders to produce instances of your own class (this is always the case unless adding @Builder to a method that doesn't return your own type), you can use @Builder(toBuilder = true) to also generate an instance method in your class called toBuilder(); it creates a new builder that starts out with all the values of this instance. You can put the @Builder.ObtainVia annotation on the parameters (in case of a constructor or method) or fields (in case of @Builder on a type) to indicate alternative means by which the value for that field/parameter is obtained from this instance. For example, you can specify a method to be invoked: @Builder.ObtainVia(method = "calculateFoo").

@@ -100,7 +100,8 @@

If a certain field/parameter is never set during a build session, then it always gets 0 / null / false. If you've put @Builder on a class (and not a method or constructor) you can instead specify the default directly on the field, and annotate the field with @Builder.Default:
- @Builder.Default private final long created = System.currentTimeMillis(); + @Builder.Default private final long created = System.currentTimeMillis();
+ Calling Lombok-generated constructors such as @NoArgsConstructor will also make use of the defaults specified using @Builder.Default however explicit constructors will no longer use the default values and will need to be set manually or call a Lombok-generated constructor such as this(); to set the defaults.

From 7830c738224b96833907cdfd5db4017bad0613f3 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 5 Dec 2023 10:34:23 -0500 Subject: [PATCH 02/65] Fixes #3564 - Duplicate StringBuffer calls to StringBuilder calls Signed-off-by: Rob Stryker --- .../core/configuration/ConfigurationFile.java | 2 +- .../eclipse/handlers/EclipseHandlerUtil.java | 4 +--- .../lombok/eclipse/agent/EclipsePatcher.java | 9 ++++++++- .../lombok/eclipse/agent/PatchJavadoc.java | 15 ++++++++++++++ .../lombok/launch/PatchFixesHider.java | 20 +++++++++++++++---- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/core/lombok/core/configuration/ConfigurationFile.java b/src/core/lombok/core/configuration/ConfigurationFile.java index 8e4e687c..121ad301 100644 --- a/src/core/lombok/core/configuration/ConfigurationFile.java +++ b/src/core/lombok/core/configuration/ConfigurationFile.java @@ -183,7 +183,7 @@ public abstract class ConfigurationFile { private static String replaceEnvironmentVariables(String fileName) { int start = 0; - StringBuffer result = new StringBuffer(); + StringBuilder result = new StringBuilder(); if (fileName.startsWith("~")) { start = 1; result.append(System.getProperty("user.home", "~")); diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index dd646e57..a6df2e12 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1331,9 +1331,7 @@ public class EclipseHandlerUtil { expressions = new Expression[] { rhs }; } if (expressions != null) for (Expression ex : expressions) { - StringBuffer sb = new StringBuffer(); - ex.print(0, sb); - raws.add(sb.toString()); + raws.add(ex.toString()); expressionValues.add(ex); guesses.add(calculateValue(ex)); } diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 52e62342..09c86e0d 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -986,6 +986,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .requestExtra(StackRequest.PARAM1) .build()); + sm.addScript(ScriptBuilder.replaceMethodCall() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) + .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) + .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) + .requestExtra(StackRequest.THIS) + .build()); + sm.addScript(ScriptBuilder.replaceMethodCall() .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) @@ -1050,7 +1057,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { sm.addScriptIfWitness(new String[] {"lombok/transform/TestWithEcj"}, ScriptBuilder.exitEarly() .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print")) .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "isImplicitCanonicalConstructor", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "java.lang.Object")) - .valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuffer", "java.lang.StringBuffer", "java.lang.Object", "java.lang.StringBuffer")) + .valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuilder", "java.lang.StringBuilder", "java.lang.Object", "java.lang.StringBuilder")) .request(StackRequest.THIS, StackRequest.PARAM2) .transplant() .build()); diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index 673c30fd..54c08ec0 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -65,6 +65,21 @@ public class PatchJavadoc { return null; } + public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuilder output, TypeDeclaration type) { + Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit); + if (docs != null) { + String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration); + String rawJavadoc = docs.get(signature); + if (rawJavadoc != null) { + for (String line : rawJavadoc.split("\r?\n")) { + ASTNode.printIndent(tab, output).append(line).append("\n"); + } + } + } + return methodDeclaration.print(tab, output); + } + + public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuffer output, TypeDeclaration type) { Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit); if (docs != null) { diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index a9db91f5..1a42f18a 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -427,20 +427,28 @@ final class PatchFixesHider { /** Contains patch code to support Javadoc for generated methods */ public static final class Javadoc { private static final Method GET_HTML; - private static final Method PRINT_METHOD; + private static final Method PRINT_METHOD_OLD; + private static final Method PRINT_METHOD_NEW; static { Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc"); GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class); - PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class); + try { + PRINT_METHOD_NEW = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuilder.class, TypeDeclaration.class); + } catch( RuntimeException e ) { + PRINT_METHOD_OLD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class); + } } public static String getHTMLContentFromSource(String original, IJavaElement member) { return (String) Util.invokeMethod(GET_HTML, original, member); } + public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuilder output, TypeDeclaration type) { + return (StringBuilder) Util.invokeMethod(PRINT_METHOD_NEW, methodDeclaration, tab, output, type); + } public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) { - return (StringBuffer) Util.invokeMethod(PRINT_METHOD, methodDeclaration, tab, output, type); + return (StringBuffer) Util.invokeMethod(PRINT_METHOD_OLD, methodDeclaration, tab, output, type); } } @@ -977,7 +985,11 @@ final class PatchFixesHider { return (method.bits & IsCanonicalConstructor) != 0 && (method.bits & IsImplicit) != 0; } - public static StringBuffer returnStringBuffer(Object p1, StringBuffer buffer) { + public static StringBuilder returnStringBuffer(Object p1, StringBuffer buffer) { + return buffer; + } + + public static StringBuilder returnStringBuilder(Object p1, StringBuilder buffer) { return buffer; } } From bd1f2adad7382cc976a38dcfc4043099e8df9141 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 5 Dec 2023 16:41:04 -0500 Subject: [PATCH 03/65] Fix some compilation errors Signed-off-by: Rob Stryker --- src/eclipseAgent/lombok/launch/PatchFixesHider.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 1a42f18a..46bb59ec 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -433,11 +433,8 @@ final class PatchFixesHider { static { Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc"); GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class); - try { - PRINT_METHOD_NEW = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuilder.class, TypeDeclaration.class); - } catch( RuntimeException e ) { - PRINT_METHOD_OLD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class); - } + PRINT_METHOD_NEW = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuilder.class, TypeDeclaration.class); + PRINT_METHOD_OLD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class); } public static String getHTMLContentFromSource(String original, IJavaElement member) { @@ -985,7 +982,7 @@ final class PatchFixesHider { return (method.bits & IsCanonicalConstructor) != 0 && (method.bits & IsImplicit) != 0; } - public static StringBuilder returnStringBuffer(Object p1, StringBuffer buffer) { + public static StringBuffer returnStringBuffer(Object p1, StringBuffer buffer) { return buffer; } From 75116df7f560c4e13c10c2f6685813113c73fd1b Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 5 Dec 2023 16:45:07 -0500 Subject: [PATCH 04/65] Add TODO with where to add reflection Signed-off-by: Rob Stryker --- src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index 54c08ec0..c2618d0b 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -72,10 +72,12 @@ public class PatchJavadoc { String rawJavadoc = docs.get(signature); if (rawJavadoc != null) { for (String line : rawJavadoc.split("\r?\n")) { + // TODO call this via reflection ASTNode.printIndent(tab, output).append(line).append("\n"); } } } + // TODO call this via reflection return methodDeclaration.print(tab, output); } @@ -87,10 +89,12 @@ public class PatchJavadoc { String rawJavadoc = docs.get(signature); if (rawJavadoc != null) { for (String line : rawJavadoc.split("\r?\n")) { + // TODO call this via reflection ASTNode.printIndent(tab, output).append(line).append("\n"); } } } + // TODO call this via reflection return methodDeclaration.print(tab, output); } From bd03b512ba45bc0d6b99e118787b8b0f4b706d9e Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 5 Dec 2023 16:55:27 -0500 Subject: [PATCH 05/65] Copy the indentation code instead of requiring dep on jdt internal Signed-off-by: Rob Stryker --- .../lombok/eclipse/agent/PatchJavadoc.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index c2618d0b..fb68b483 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -72,8 +72,7 @@ public class PatchJavadoc { String rawJavadoc = docs.get(signature); if (rawJavadoc != null) { for (String line : rawJavadoc.split("\r?\n")) { - // TODO call this via reflection - ASTNode.printIndent(tab, output).append(line).append("\n"); + printIndent(tab, output).append(line).append("\n"); } } } @@ -89,8 +88,7 @@ public class PatchJavadoc { String rawJavadoc = docs.get(signature); if (rawJavadoc != null) { for (String line : rawJavadoc.split("\r?\n")) { - // TODO call this via reflection - ASTNode.printIndent(tab, output).append(line).append("\n"); + printIndent(tab, output).append(line).append("\n"); } } } @@ -98,6 +96,16 @@ public class PatchJavadoc { return methodDeclaration.print(tab, output); } + private static StringBuilder printIndent(int indent, StringBuilder output) { + for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$ + return output; + } + + private static StringBuffer printIndent(int indent, StringBuffer output) { + for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$ + return output; + } + private static class Signature { static final String getSignature(SourceMethod sourceMethod) { StringBuilder sb = new StringBuilder(); From c784c7bb7ab80bbc5f78abae60e4f203742d74f3 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 5 Dec 2023 16:57:54 -0500 Subject: [PATCH 06/65] One compilation error left Signed-off-by: Rob Stryker --- src/core/lombok/core/configuration/ConfigurationFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lombok/core/configuration/ConfigurationFile.java b/src/core/lombok/core/configuration/ConfigurationFile.java index 121ad301..8e4e687c 100644 --- a/src/core/lombok/core/configuration/ConfigurationFile.java +++ b/src/core/lombok/core/configuration/ConfigurationFile.java @@ -183,7 +183,7 @@ public abstract class ConfigurationFile { private static String replaceEnvironmentVariables(String fileName) { int start = 0; - StringBuilder result = new StringBuilder(); + StringBuffer result = new StringBuffer(); if (fileName.startsWith("~")) { start = 1; result.append(System.getProperty("user.home", "~")); From c64c5a93110b17662641a5071b5efffe1d41c348 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Wed, 6 Dec 2023 02:01:40 -0500 Subject: [PATCH 07/65] Get patch to compile Signed-off-by: Rob Stryker --- .../lombok/eclipse/agent/PatchJavadoc.java | 70 +++++++++++++++++-- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index fb68b483..077d748a 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -24,6 +24,7 @@ package lombok.eclipse.agent; import static lombok.eclipse.EcjAugments.CompilationUnit_javadoc; import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.eclipse.jdt.core.ICompilationUnit; @@ -76,8 +77,34 @@ public class PatchJavadoc { } } } - // TODO call this via reflection - return methodDeclaration.print(tab, output); + String methodName = "print"; + Method builderMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuilder.class); + if( builderMethod != null ) { + try { + return (StringBuilder)builderMethod.invoke(methodDeclaration, tab, output); + } catch( IllegalAccessException e ) { + // ignore + } catch( InvocationTargetException f ) { + // ignore + } + } + + // Should never happen + Method bufferMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuffer.class); + if( bufferMethod != null ) { + try { + StringBuffer sb = new StringBuffer(); + StringBuffer out = (StringBuffer)bufferMethod.invoke(methodDeclaration, tab, sb); + output.append(out.toString()); + return output; + } catch( IllegalAccessException e ) { + // ignore + } catch( InvocationTargetException f ) { + // ignore + } + } + // Should really never happen + return output; } @@ -92,8 +119,43 @@ public class PatchJavadoc { } } } - // TODO call this via reflection - return methodDeclaration.print(tab, output); + + String methodName = "print"; + Method bufferMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuffer.class); + if( bufferMethod != null ) { + try { + return (StringBuffer)bufferMethod.invoke(methodDeclaration, tab, output); + } catch( IllegalAccessException e ) { + // ignore + } catch( InvocationTargetException f ) { + // ignore + } + } + + // Should never happen + Method builderMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuilder.class); + if( builderMethod != null ) { + try { + StringBuilder sb = new StringBuilder(); + StringBuilder out = (StringBuilder)builderMethod.invoke(methodDeclaration, tab, sb); + output.append(out.toString()); + return output; + } catch( IllegalAccessException e ) { + // ignore + } catch( InvocationTargetException f ) { + // ignore + } + } + // Should really never happen + return output; + } + + public static Method findMethodOrNull(Class type, String name, Class... parameterTypes) { + try { + return type.getDeclaredMethod(name, parameterTypes); + } catch (NoSuchMethodException e) { + return null; + } } private static StringBuilder printIndent(int indent, StringBuilder output) { From 513604491919d61c0685ffde2c77c4b52c7af2e2 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 10 Dec 2023 09:45:19 +0100 Subject: [PATCH 08/65] Add tests for eclipse 2023-12 and integration builds --- buildScripts/ivy.xml | 15 ++ buildScripts/setup.ant.xml | 199 +++++------------- buildScripts/tests.ant.xml | 38 ++++ .../lombok/eclipse/dependencies/Child.java | 8 + .../DownloadEclipseDependencies.java | 82 ++++---- .../lombok/eclipse/dependencies/Provided.java | 12 ++ .../eclipse/dependencies/Repository.java | 18 ++ .../lombok/eclipse/dependencies/Required.java | 17 ++ .../eclipse/dependencies/UniqueQueue.java | 21 ++ .../lombok/eclipse/dependencies/Unit.java | 27 +++ .../eclipse/dependencies/UpdateSite.java | 168 +++++++++++++++ 11 files changed, 407 insertions(+), 198 deletions(-) create mode 100644 src/support/lombok/eclipse/dependencies/Child.java create mode 100644 src/support/lombok/eclipse/dependencies/Provided.java create mode 100644 src/support/lombok/eclipse/dependencies/Repository.java create mode 100644 src/support/lombok/eclipse/dependencies/Required.java create mode 100644 src/support/lombok/eclipse/dependencies/UniqueQueue.java create mode 100644 src/support/lombok/eclipse/dependencies/Unit.java create mode 100644 src/support/lombok/eclipse/dependencies/UpdateSite.java diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index b165300b..6a5cd0eb 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -32,6 +32,7 @@ + @@ -64,6 +65,7 @@ + @@ -132,6 +134,19 @@ + + + + + + + + + + + + + diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index 39954a02..c0521316 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -45,25 +45,21 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - Full eclipse testing requires downloading a native SWT binding. This script knows how to download for OS = [mac, linux, or windows] and architecture = [aarch64 or x86-64]. You have something different, you unique snowflake you. Your OS: "${os.name}", Your arch: "${os.arch}". + Full eclipse testing requires downloading a native SWT binding. This script knows how to download for OS = [mac, linux, or windows] and architecture = [aarch64 or x86-64]. You have something different, you unique snowflake you. Your OS: "${os.name}", Your arch: "${os.arch}". @@ -160,15 +156,23 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - + - + - + + + + + + + + + @@ -192,13 +196,28 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - - - - + + + + + + + + + + + + + + + + + + + @@ -206,133 +225,9 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml index c7f7a865..ade6fbff 100644 --- a/buildScripts/tests.ant.xml +++ b/buildScripts/tests.ant.xml @@ -218,6 +218,36 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -261,6 +291,14 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn + + + + + + + + diff --git a/src/support/lombok/eclipse/dependencies/Child.java b/src/support/lombok/eclipse/dependencies/Child.java new file mode 100644 index 00000000..06b93793 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/Child.java @@ -0,0 +1,8 @@ +package lombok.eclipse.dependencies; + +import javax.xml.bind.annotation.XmlAttribute; + +public class Child { + @XmlAttribute + String location; +} \ No newline at end of file diff --git a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java index 2ff6839e..2391a1a9 100644 --- a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java +++ b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java @@ -7,71 +7,57 @@ import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.List; +import java.util.Set; /** * Download eclipse bundles. */ public class DownloadEclipseDependencies { - public static void main(String[] args) throws IOException { + public static void main(String[] args) throws Exception { String target = args[0]; String eclipseVersion = args[1]; - String updatePage = args[2]; - String[] packages = Arrays.copyOfRange(args, 3, args.length); + String updateSiteUrl = args[2]; + boolean resolveDependencies = Boolean.parseBoolean(args[3]); + List bundles = Arrays.asList(Arrays.copyOfRange(args, 4, args.length)); + + UpdateSite updateSite = new UpdateSite(); + updateSite.read(updateSiteUrl); + + final Set artifacts; + if (resolveDependencies) { + artifacts = updateSite.resolveWithDependencies(bundles); + } else { + artifacts = updateSite.resolveWithoutDependencies(bundles); + } String pluginTarget = target + "/" + eclipseVersion + "/plugins/"; + String pluginSource = updateSite.getResolvedUrl() + "/plugins/"; - String indexData = readUrlAsString(updatePage); - - for (String pkg : packages) { - Matcher matcher = Pattern.compile("(" + pkg.replace(".", "\\.") + "_.*?\\.jar)").matcher(indexData); - if (matcher.find()) { - String path = matcher.group(1); - - try { - downloadFile(path, updatePage, pluginTarget); - } catch (Exception e) { - } - - int index = path.lastIndexOf("_"); - String source = path.substring(0, index) + ".source" + path.substring(index); - if (indexData.contains(source)) { - try { - downloadFile(source, updatePage, pluginTarget); - } catch (Exception e) { - } - } - } else { - System.out.println("Bundle \"" + pkg + "\" not found"); + for (String artifact : artifacts) { + try { + downloadFile(artifact, pluginSource, pluginTarget); + } catch (Exception e) { + } + + int index = artifact.lastIndexOf("_"); + String source = artifact.substring(0, index) + ".source" + artifact.substring(index); + try { + downloadFile(source, pluginSource, pluginTarget); + } catch (Exception e) { } } writeEclipseLibrary(target, eclipseVersion); } - private static String readUrlAsString(String url) throws MalformedURLException, IOException { - InputStream in = getStreamForUrl(url); - - StringBuilder sb = new StringBuilder(); - - int bufferSize = 1024; - char[] buffer = new char[bufferSize]; - InputStreamReader reader = new InputStreamReader(in, "UTF-8"); - for (int count = 0; (count = reader.read(buffer, 0, bufferSize)) > 0;) { - sb.append(buffer, 0, count); - } - return sb.toString(); - } - private static void downloadFile(String filename, String repositoryUrl, String target) throws IOException { new File(target).mkdirs(); File targetFile = new File(target, filename); @@ -87,10 +73,13 @@ public class DownloadEclipseDependencies { out = new FileOutputStream(targetFile); copy(in, out); System.out.println("[done]"); - } catch(IOException e) { + } catch (IOException e) { System.out.println("[error]"); } finally { - if (in != null) try { in.close(); } catch (Exception ignore) {} + if (in != null) try { + in.close(); + } catch (Exception ignore) { + } if (out != null) out.close(); } } @@ -111,7 +100,7 @@ public class DownloadEclipseDependencies { InputStream in = new BufferedInputStream(connection.getInputStream()); return in; } - + private static void writeEclipseLibrary(String target, String eclipseVersion) throws IOException { StringBuilder sb = new StringBuilder(); sb.append("\n"); @@ -121,7 +110,8 @@ public class DownloadEclipseDependencies { sb.append("\" systemlibrary=\"false\">\n"); File[] files = new File(new File(target, eclipseVersion), "plugins").listFiles(new FilenameFilter() { - @Override public boolean accept(File dir, String name) { + @Override + public boolean accept(File dir, String name) { return name.endsWith(".jar") && !name.contains(".source_"); } }); diff --git a/src/support/lombok/eclipse/dependencies/Provided.java b/src/support/lombok/eclipse/dependencies/Provided.java new file mode 100644 index 00000000..6ca7d6f3 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/Provided.java @@ -0,0 +1,12 @@ +package lombok.eclipse.dependencies; + +import javax.xml.bind.annotation.XmlAttribute; + +public class Provided { + @XmlAttribute + String namespace; + @XmlAttribute + String name; + @XmlAttribute + String version; +} diff --git a/src/support/lombok/eclipse/dependencies/Repository.java b/src/support/lombok/eclipse/dependencies/Repository.java new file mode 100644 index 00000000..8423d7ee --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/Repository.java @@ -0,0 +1,18 @@ +package lombok.eclipse.dependencies; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Repository { + @XmlElementWrapper(name = "children") + @XmlElement(name="child") + List children; + + @XmlElementWrapper(name = "units") + @XmlElement(name="unit") + List units; +} \ No newline at end of file diff --git a/src/support/lombok/eclipse/dependencies/Required.java b/src/support/lombok/eclipse/dependencies/Required.java new file mode 100644 index 00000000..5f1f895d --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/Required.java @@ -0,0 +1,17 @@ +package lombok.eclipse.dependencies; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +public class Required { + @XmlAttribute + String namespace; + @XmlAttribute + String name; + @XmlAttribute + String range; + @XmlAttribute + boolean optional; + @XmlElement + String filter; +} diff --git a/src/support/lombok/eclipse/dependencies/UniqueQueue.java b/src/support/lombok/eclipse/dependencies/UniqueQueue.java new file mode 100644 index 00000000..7ec4a38c --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/UniqueQueue.java @@ -0,0 +1,21 @@ +package lombok.eclipse.dependencies; + +import java.util.ArrayDeque; +import java.util.HashSet; +import java.util.Set; + +/** + * A incomplete implementation of a queue that maintains a history of all queued items and ensures unique elements. + * Elements cannot be added to the queue if they already exist in the history. + */ +public class UniqueQueue extends ArrayDeque { + private Set added = new HashSet<>(); + + @Override + public boolean add(T e) { + if (added.add(e)) { + return super.add(e); + } + return false; + } +} diff --git a/src/support/lombok/eclipse/dependencies/Unit.java b/src/support/lombok/eclipse/dependencies/Unit.java new file mode 100644 index 00000000..51827cf0 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/Unit.java @@ -0,0 +1,27 @@ +package lombok.eclipse.dependencies; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +public class Unit { + @XmlAttribute + String id; + @XmlAttribute + String version; + + @XmlElementWrapper(name = "provides") + @XmlElement(name="provided") + List provides; + + @XmlElementWrapper(name = "requires") + @XmlElement(name="required") + List requires; + + @Override + public String toString() { + return id + "_" + version; + } +} diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java new file mode 100644 index 00000000..b49acdfb --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java @@ -0,0 +1,168 @@ +package lombok.eclipse.dependencies; + +import java.io.BufferedInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; + +public class UpdateSite { + private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); + private static final String OSGI_OS = OS_NAME.contains("windows") ? "windows" : OS_NAME.contains("mac") ? "mac" : "linux"; + private static final String OS_ARCH = System.getProperty("os.arch"); + private static final String OSGI_ARCH = OS_ARCH.equals("aarch64") ? "aarch64" : "x86_64"; + + private JAXBContext jaxbContext; + private Repository repository; + private Map> providesIndex; + private String resolvedUrl; + + public UpdateSite() throws JAXBException { + jaxbContext = JAXBContext.newInstance(Repository.class); + providesIndex = new HashMap<>(); + } + + public void read(String url) throws Exception { + String currentUrl = url; + try { + while (true) { + String child = resolveNextChild(currentUrl); + if (child.startsWith("https://")) { + currentUrl = child; + } else { + currentUrl += child; + } + } + } catch (FileNotFoundException e) { + // Found the real repository + } + + resolvedUrl = currentUrl; + + try (InputStream inputStream = readJarOrXml(resolvedUrl, "content")) { + repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(inputStream); + + // Build index + for (Unit unit : repository.units) { + for (Provided provides : unit.provides) { + providesIndex.computeIfAbsent(provides.namespace + ":" + provides.name, k -> new ArrayList<>()).add(unit); + } + } + } + ; + } + + public Set resolveWithoutDependencies(List dependencies) { + return resolve(dependencies, false); + } + + public Set resolveWithDependencies(List dependencies) { + return resolve(dependencies, true); + } + + private Set resolve(List dependencies, boolean withDependencies) { + Queue toResolve = new UniqueQueue<>(); + for (String dependency : dependencies) { + toResolve.add(dependency); + } + Set resolved = new HashSet<>(); + while (!toResolve.isEmpty()) { + String next = toResolve.poll(); + + List providedUnits = providesIndex.get(next); + // Skip unknown + if (providedUnits == null) { + System.out.println("Skipping unknown unit " + next); + continue; + } + // Skip ambiguous (we could use version ranges to solve that...) + if (providedUnits.size() > 1) { + boolean alreadyResolved = providedUnits.stream().anyMatch(resolved::contains); + if (!alreadyResolved) { + System.out.println("Ambiguous resolution for " + next + ": " + providedUnits.toString()); + continue; + } + } + + Unit unit = providedUnits.get(0); + resolved.add(unit); + + if (withDependencies && unit.requires != null) { + for (Required required : unit.requires) { + if (required.optional) continue; + if (!matchesFilter(required.filter)) continue; + + toResolve.add(required.namespace + ":" + required.name); + } + } + } + + return resolved.stream().map(u -> u.toString() + ".jar").collect(Collectors.toSet()); + } + + // Dummy implementation + private boolean matchesFilter(String filter) { + if (filter == null) { + return true; + } + if (filter.contains("osgi.arch=") && !filter.contains("osgi.arch=" + OSGI_ARCH)) { + return false; + } + if (filter.contains("osgi.os=") && !filter.contains("osgi.os=" + OSGI_OS)) { + return false; + } + return true; + } + + private String resolveNextChild(String currentUrl) throws MalformedURLException, IOException, JAXBException { + try (InputStream inputStream = readJarOrXml(currentUrl, "compositeContent")) { + Repository repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(inputStream); + Child lastChild = repository.children.get(repository.children.size() - 1); + return lastChild.location; + } + } + + private InputStream readJarOrXml(String url, String name) throws MalformedURLException, IOException { + try { + return getStreamForUrl(url + "/" + name + ".xml"); + } catch (FileNotFoundException e) { + System.out.println("Not found, trying jar"); + } + ZipInputStream zipInputStream = new ZipInputStream(getStreamForUrl(url + "/" + name + ".jar")); + ZipEntry entry; + while ((entry = zipInputStream.getNextEntry()) != null) { + if (entry.getName().equals(name + ".xml")) { + return zipInputStream; + } + } + throw new FileNotFoundException(); + } + + private static InputStream getStreamForUrl(String url) throws IOException, MalformedURLException { + System.out.println("Reading " + url); + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setRequestProperty("User-Agent", "lombok"); + connection.setRequestProperty("Accept", "*/*"); + InputStream in = new BufferedInputStream(connection.getInputStream()); + return in; + } + + public String getResolvedUrl() { + return resolvedUrl; + } +} From 6befa63ac631e957724967a95fc5746bd92630dc Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 10 Dec 2023 09:50:45 +0100 Subject: [PATCH 09/65] Add eclipse 2023-12 tests to actions --- .github/workflows/ant.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 07a77430..89d71dda 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -101,9 +101,11 @@ jobs: - eclipse-202006-jdk8 - eclipse-202212 - eclipse-202309 + - eclipse-202312 - eclipse-oxygen-full - eclipse-2022-03-full - eclipse-2023-09-full + - eclipse-2023-12-full - ecj11 - ecj14 - ecj16 From 59c91fd2a290b87118533a59f357bca308b23b86 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 10 Dec 2023 10:18:24 +0100 Subject: [PATCH 10/65] Add handling for JRE dependencies --- .../eclipse/dependencies/UpdateSite.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java index b49acdfb..6201a807 100644 --- a/src/support/lombok/eclipse/dependencies/UpdateSite.java +++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java @@ -90,16 +90,26 @@ public class UpdateSite { System.out.println("Skipping unknown unit " + next); continue; } + // Remove a.jre.javase dependency + List filteredProvidedUnits = providedUnits.stream() + .filter(u -> !u.id.equals("a.jre.javase")) // Remove + .collect(Collectors.toList()); + + if (filteredProvidedUnits.size() == 0) { + // This is a JDK only dependency, skip + continue; + } + // Skip ambiguous (we could use version ranges to solve that...) - if (providedUnits.size() > 1) { - boolean alreadyResolved = providedUnits.stream().anyMatch(resolved::contains); + if (filteredProvidedUnits.size() > 1) { + boolean alreadyResolved = filteredProvidedUnits.stream().anyMatch(resolved::contains); if (!alreadyResolved) { - System.out.println("Ambiguous resolution for " + next + ": " + providedUnits.toString()); + System.out.println("Ambiguous resolution for " + next + ": " + filteredProvidedUnits.toString()); continue; } } - Unit unit = providedUnits.get(0); + Unit unit = filteredProvidedUnits.get(0); resolved.add(unit); if (withDependencies && unit.requires != null) { From ebb166cd521207fe98c05fa3ab6b3dd8fee4c7fe Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 10 Dec 2023 11:19:04 +0100 Subject: [PATCH 11/65] Add ambiguous javax.el-api dependency --- buildScripts/setup.ant.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index c0521316..f0ac003e 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -201,11 +201,14 @@ This buildfile is part of projectlombok.org. It sets up the build itself. + + + + - From 0d53abc62964359993e6dcf0d9136409f408aefa Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 15 Dec 2023 21:43:18 +0100 Subject: [PATCH 12/65] Add protection against XXE --- .../eclipse/dependencies/UpdateSite.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java index 6201a807..93da4120 100644 --- a/src/support/lombok/eclipse/dependencies/UpdateSite.java +++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java @@ -2,10 +2,8 @@ package lombok.eclipse.dependencies; import java.io.BufferedInputStream; import java.io.FileNotFoundException; -import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -18,8 +16,13 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; + +import org.xml.sax.InputSource; public class UpdateSite { private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); @@ -31,10 +34,17 @@ public class UpdateSite { private Repository repository; private Map> providesIndex; private String resolvedUrl; + private SAXParserFactory saxParserFactory; - public UpdateSite() throws JAXBException { + public UpdateSite() throws Exception { jaxbContext = JAXBContext.newInstance(Repository.class); providesIndex = new HashMap<>(); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + spf.setXIncludeAware(false); + saxParserFactory = spf; } public void read(String url) throws Exception { @@ -55,7 +65,7 @@ public class UpdateSite { resolvedUrl = currentUrl; try (InputStream inputStream = readJarOrXml(resolvedUrl, "content")) { - repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(inputStream); + repository = unmarshalRepository(inputStream); // Build index for (Unit unit : repository.units) { @@ -139,15 +149,21 @@ public class UpdateSite { return true; } - private String resolveNextChild(String currentUrl) throws MalformedURLException, IOException, JAXBException { + private String resolveNextChild(String currentUrl) throws Exception { try (InputStream inputStream = readJarOrXml(currentUrl, "compositeContent")) { - Repository repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(inputStream); + Repository repository = unmarshalRepository(inputStream); Child lastChild = repository.children.get(repository.children.size() - 1); return lastChild.location; } } + + private Repository unmarshalRepository(InputStream inputStream) throws Exception { + Source source = new SAXSource(saxParserFactory.newSAXParser().getXMLReader(), new InputSource(inputStream)); + Repository repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(source); + return repository; + } - private InputStream readJarOrXml(String url, String name) throws MalformedURLException, IOException { + private InputStream readJarOrXml(String url, String name) throws Exception { try { return getStreamForUrl(url + "/" + name + ".xml"); } catch (FileNotFoundException e) { @@ -163,7 +179,7 @@ public class UpdateSite { throw new FileNotFoundException(); } - private static InputStream getStreamForUrl(String url) throws IOException, MalformedURLException { + private static InputStream getStreamForUrl(String url) throws Exception { System.out.println("Reading " + url); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("User-Agent", "lombok"); From 9d55da8e6d9cdbec1f00c15c739c6654ec1c6946 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Mon, 11 Dec 2023 23:46:23 +0100 Subject: [PATCH 13/65] Simplify, move and fix patches --- .../lombok/eclipse/agent/EclipsePatcher.java | 46 +++++--- .../lombok/eclipse/agent/PatchJavadoc.java | 102 ------------------ .../lombok/launch/PatchFixesHider.java | 34 +++++- 3 files changed, 62 insertions(+), 120 deletions(-) diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 09c86e0d..1616d956 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -985,20 +985,6 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "getHTMLContentFromSource", "java.lang.String", "java.lang.String", "org.eclipse.jdt.core.IJavaElement")) .requestExtra(StackRequest.PARAM1) .build()); - - sm.addScript(ScriptBuilder.replaceMethodCall() - .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) - .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) - .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) - .requestExtra(StackRequest.THIS) - .build()); - - sm.addScript(ScriptBuilder.replaceMethodCall() - .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) - .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) - .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) - .requestExtra(StackRequest.THIS) - .build()); sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField() .fieldName("$javadoc") @@ -1048,19 +1034,45 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { } private static void patchForTests(ScriptManager sm) { - sm.addScriptIfWitness(new String[] {"lombok/eclipse/EclipseRunner"}, ScriptBuilder.wrapReturnValue() + String[] ECLIPSE_TEST_CLASSES = new String[] {"lombok/transform/TestWithEcj", "lombok/eclipse/EclipseRunner"}; + + // Add support for javadoc in tests + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.replaceMethodCall() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) + .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) + .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "printMethod", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) + .requestExtra(StackRequest.THIS) + .build()); + + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.replaceMethodCall() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) + .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) + .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) + .requestExtra(StackRequest.THIS) + .build()); + + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.wrapReturnValue() .target(new MethodTarget("org.osgi.framework.FrameworkUtil", "getBundle", "org.osgi.framework.Bundle", "java.lang.Class")) .request(StackRequest.RETURN_VALUE, StackRequest.PARAM1) .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "getBundle", "java.lang.Object", "java.lang.Object", "java.lang.Class")) .build()); - sm.addScriptIfWitness(new String[] {"lombok/transform/TestWithEcj"}, ScriptBuilder.exitEarly() - .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print")) + // Remove implicit canonical constructors in tests + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder")) .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "isImplicitCanonicalConstructor", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "java.lang.Object")) .valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuilder", "java.lang.StringBuilder", "java.lang.Object", "java.lang.StringBuilder")) .request(StackRequest.THIS, StackRequest.PARAM2) .transplant() .build()); + + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) + .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "isImplicitCanonicalConstructor", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "java.lang.Object")) + .valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuffer", "java.lang.StringBuffer", "java.lang.Object", "java.lang.StringBuffer")) + .request(StackRequest.THIS, StackRequest.PARAM2) + .transplant() + .build()); } } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index 077d748a..f270e19f 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -65,108 +65,6 @@ public class PatchJavadoc { return null; } - - public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuilder output, TypeDeclaration type) { - Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit); - if (docs != null) { - String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration); - String rawJavadoc = docs.get(signature); - if (rawJavadoc != null) { - for (String line : rawJavadoc.split("\r?\n")) { - printIndent(tab, output).append(line).append("\n"); - } - } - } - String methodName = "print"; - Method builderMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuilder.class); - if( builderMethod != null ) { - try { - return (StringBuilder)builderMethod.invoke(methodDeclaration, tab, output); - } catch( IllegalAccessException e ) { - // ignore - } catch( InvocationTargetException f ) { - // ignore - } - } - - // Should never happen - Method bufferMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuffer.class); - if( bufferMethod != null ) { - try { - StringBuffer sb = new StringBuffer(); - StringBuffer out = (StringBuffer)bufferMethod.invoke(methodDeclaration, tab, sb); - output.append(out.toString()); - return output; - } catch( IllegalAccessException e ) { - // ignore - } catch( InvocationTargetException f ) { - // ignore - } - } - // Should really never happen - return output; - } - - - public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuffer output, TypeDeclaration type) { - Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit); - if (docs != null) { - String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration); - String rawJavadoc = docs.get(signature); - if (rawJavadoc != null) { - for (String line : rawJavadoc.split("\r?\n")) { - printIndent(tab, output).append(line).append("\n"); - } - } - } - - String methodName = "print"; - Method bufferMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuffer.class); - if( bufferMethod != null ) { - try { - return (StringBuffer)bufferMethod.invoke(methodDeclaration, tab, output); - } catch( IllegalAccessException e ) { - // ignore - } catch( InvocationTargetException f ) { - // ignore - } - } - - // Should never happen - Method builderMethod = findMethodOrNull(AbstractMethodDeclaration.class, methodName, int.class, StringBuilder.class); - if( builderMethod != null ) { - try { - StringBuilder sb = new StringBuilder(); - StringBuilder out = (StringBuilder)builderMethod.invoke(methodDeclaration, tab, sb); - output.append(out.toString()); - return output; - } catch( IllegalAccessException e ) { - // ignore - } catch( InvocationTargetException f ) { - // ignore - } - } - // Should really never happen - return output; - } - - public static Method findMethodOrNull(Class type, String name, Class... parameterTypes) { - try { - return type.getDeclaredMethod(name, parameterTypes); - } catch (NoSuchMethodException e) { - return null; - } - } - - private static StringBuilder printIndent(int indent, StringBuilder output) { - for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$ - return output; - } - - private static StringBuffer printIndent(int indent, StringBuffer output) { - for (int i = indent; i > 0; i--) output.append(" "); //$NON-NLS-1$ - return output; - } private static class Signature { static final String getSignature(SourceMethod sourceMethod) { diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 46bb59ec..6c3459bf 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -21,7 +21,7 @@ */ package lombok.launch; -import static lombok.eclipse.EcjAugments.ASTNode_generatedBy; +import static lombok.eclipse.EcjAugments.*; import static lombok.eclipse.Eclipse.*; import java.io.BufferedOutputStream; @@ -33,6 +33,7 @@ import java.lang.reflect.Method; import java.security.CodeSource; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Stack; import org.eclipse.core.runtime.CoreException; @@ -70,6 +71,7 @@ import org.eclipse.jdt.internal.corext.refactoring.code.CallContext; import org.eclipse.jdt.internal.corext.refactoring.code.SourceProvider; import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment; +import lombok.eclipse.handlers.EclipseHandlerUtil; import lombok.permit.Permit; /** These contain a mix of the following: @@ -956,6 +958,36 @@ final class PatchFixesHider { } public static class Tests { + public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) { + return (StringBuffer) printMethod(methodDeclaration, tab, (Object) output, type); + } + + public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuilder output, TypeDeclaration type) { + return (StringBuilder) printMethod(methodDeclaration, tab, (Object) output, type); + } + + public static Object printMethod(AbstractMethodDeclaration methodDeclaration, int tab, Object output, TypeDeclaration type) { + Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit); + Method printIndent = Permit.permissiveGetMethod(org.eclipse.jdt.internal.compiler.ast.ASTNode.class, "printIndent", int.class, output.getClass()); + if (docs != null) { + String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration); + String rawJavadoc = docs.get(signature); + if (rawJavadoc != null) { + for (String line : rawJavadoc.split("\r?\n")) { + try { + Appendable sb = (Appendable) Permit.invoke(printIndent, null, tab, output); + sb.append(line).append("\n"); + } catch (Throwable e) { + // Ignore + } + } + } + } + Method printMethodDeclaration = Permit.permissiveGetMethod(AbstractMethodDeclaration.class, "print", int.class, output.getClass()); + Permit.invokeSneaky(printMethodDeclaration, methodDeclaration, tab, output); + return output; + } + public static Object getBundle(Object original, Class c) { if (original != null) { return original; From fb09a99fae385cc6a83d03debc2264975e816278 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 17 Dec 2023 13:04:40 +0100 Subject: [PATCH 14/65] [fixes #3559[fixes #3497] Treat nested records as static --- src/core/lombok/eclipse/EclipseNode.java | 2 +- .../eclipse/handlers/EclipseHandlerUtil.java | 2 +- src/core/lombok/javac/JavacNode.java | 2 +- .../javac/handlers/JavacHandlerUtil.java | 6 +-- .../after-delombok/BuilderOnNestedClass.java | 49 +++++++++++++++++++ .../after-delombok/BuilderOnNestedRecord.java | 41 ++++++++++++++++ .../after-delombok/WithOnNestedRecord.java | 21 ++++++++ .../after-ecj/BuilderOnNestedClass.java | 35 +++++++++++++ .../after-ecj/BuilderOnNestedRecord.java | 30 ++++++++++++ .../after-ecj/WithOnNestedRecord.java | 23 +++++++++ .../resource/before/BuilderOnNestedClass.java | 8 +++ .../before/BuilderOnNestedRecord.java | 7 +++ test/transform/resource/before/RecordNonNull | 0 .../resource/before/WithOnNestedRecord.java | 9 ++++ 14 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 test/transform/resource/after-delombok/BuilderOnNestedClass.java create mode 100644 test/transform/resource/after-delombok/BuilderOnNestedRecord.java create mode 100644 test/transform/resource/after-delombok/WithOnNestedRecord.java create mode 100644 test/transform/resource/after-ecj/BuilderOnNestedClass.java create mode 100644 test/transform/resource/after-ecj/BuilderOnNestedRecord.java create mode 100644 test/transform/resource/after-ecj/WithOnNestedRecord.java create mode 100644 test/transform/resource/before/BuilderOnNestedClass.java create mode 100644 test/transform/resource/before/BuilderOnNestedRecord.java delete mode 100644 test/transform/resource/before/RecordNonNull create mode 100644 test/transform/resource/before/WithOnNestedRecord.java diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java index 4950aeef..cd7bae76 100644 --- a/src/core/lombok/eclipse/EclipseNode.java +++ b/src/core/lombok/eclipse/EclipseNode.java @@ -217,7 +217,7 @@ public class EclipseNode extends lombok.core.LombokNode params) { JCClassDecl td = (JCClassDecl) type.get(); - boolean instance = (td.mods.flags & Flags.STATIC) == 0; + boolean instance = !type.isStatic(); return namePlusTypeParamsToTypeReference(maker, type.up(), td.name, instance, params, List.nil()); } public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode type, List params, List annotations) { JCClassDecl td = (JCClassDecl) type.get(); - boolean instance = (td.mods.flags & Flags.STATIC) == 0; + boolean instance = !type.isStatic(); return namePlusTypeParamsToTypeReference(maker, type.up(), td.name, instance, params, annotations); } @@ -2051,7 +2051,7 @@ public class JavacHandlerUtil { JCExpression r = null; if (parentType != null && parentType.getKind() == Kind.TYPE && !parentType.getName().isEmpty()) { JCClassDecl td = (JCClassDecl) parentType.get(); - boolean outerInstance = instance && ((td.mods.flags & Flags.STATIC) == 0); + boolean outerInstance = instance && !parentType.isStatic(); List outerParams = instance ? td.typarams : List.nil(); r = namePlusTypeParamsToTypeReference(maker, parentType.up(), td.name, outerInstance, outerParams, List.nil()); } diff --git a/test/transform/resource/after-delombok/BuilderOnNestedClass.java b/test/transform/resource/after-delombok/BuilderOnNestedClass.java new file mode 100644 index 00000000..76e69f78 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderOnNestedClass.java @@ -0,0 +1,49 @@ +public class BuilderOnNestedClass { + private T t; + + + public static class Nested { + private String a; + + @java.lang.SuppressWarnings("all") + Nested(final String a) { + this.a = a; + } + + + @java.lang.SuppressWarnings("all") + public static class NestedBuilder { + @java.lang.SuppressWarnings("all") + private String a; + + @java.lang.SuppressWarnings("all") + NestedBuilder() { + } + + /** + * @return {@code this}. + */ + @java.lang.SuppressWarnings("all") + public BuilderOnNestedClass.Nested.NestedBuilder a(final String a) { + this.a = a; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderOnNestedClass.Nested build() { + return new BuilderOnNestedClass.Nested(this.a); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderOnNestedClass.Nested.NestedBuilder(a=" + this.a + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static BuilderOnNestedClass.Nested.NestedBuilder builder() { + return new BuilderOnNestedClass.Nested.NestedBuilder(); + } + } +} diff --git a/test/transform/resource/after-delombok/BuilderOnNestedRecord.java b/test/transform/resource/after-delombok/BuilderOnNestedRecord.java new file mode 100644 index 00000000..83de7e06 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderOnNestedRecord.java @@ -0,0 +1,41 @@ +// version 14: +public record BuilderOnNestedRecord(T t) { + + public record Nested(String a) { + + @java.lang.SuppressWarnings("all") + public static class NestedBuilder { + @java.lang.SuppressWarnings("all") + private String a; + + @java.lang.SuppressWarnings("all") + NestedBuilder() { + } + + /** + * @return {@code this}. + */ + @java.lang.SuppressWarnings("all") + public BuilderOnNestedRecord.Nested.NestedBuilder a(final String a) { + this.a = a; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderOnNestedRecord.Nested build() { + return new BuilderOnNestedRecord.Nested(this.a); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderOnNestedRecord.Nested.NestedBuilder(a=" + this.a + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static BuilderOnNestedRecord.Nested.NestedBuilder builder() { + return new BuilderOnNestedRecord.Nested.NestedBuilder(); + } + } +} diff --git a/test/transform/resource/after-delombok/WithOnNestedRecord.java b/test/transform/resource/after-delombok/WithOnNestedRecord.java new file mode 100644 index 00000000..86c31ac6 --- /dev/null +++ b/test/transform/resource/after-delombok/WithOnNestedRecord.java @@ -0,0 +1,21 @@ +// version 14: +public class WithOnNestedRecord { + + public record Nested(String a, String b) { + /** + * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed). + */ + @java.lang.SuppressWarnings("all") + public WithOnNestedRecord.Nested withA(final String a) { + return this.a == a ? this : new WithOnNestedRecord.Nested(a, this.b); + } + + /** + * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed). + */ + @java.lang.SuppressWarnings("all") + public WithOnNestedRecord.Nested withB(final String b) { + return this.b == b ? this : new WithOnNestedRecord.Nested(this.a, b); + } + } +} diff --git a/test/transform/resource/after-ecj/BuilderOnNestedClass.java b/test/transform/resource/after-ecj/BuilderOnNestedClass.java new file mode 100644 index 00000000..b100223b --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderOnNestedClass.java @@ -0,0 +1,35 @@ +public class BuilderOnNestedClass { + public static @lombok.Builder class Nested { + public static @java.lang.SuppressWarnings("all") class NestedBuilder { + private @java.lang.SuppressWarnings("all") String a; + @java.lang.SuppressWarnings("all") NestedBuilder() { + super(); + } + /** + * @return {@code this}. + */ + public @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested.NestedBuilder a(final String a) { + this.a = a; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested build() { + return new BuilderOnNestedClass.Nested(this.a); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderOnNestedClass.Nested.NestedBuilder(a=" + this.a) + ")"); + } + } + private String a; + @java.lang.SuppressWarnings("all") Nested(final String a) { + super(); + this.a = a; + } + public static @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested.NestedBuilder builder() { + return new BuilderOnNestedClass.Nested.NestedBuilder(); + } + } + private T t; + public BuilderOnNestedClass() { + super(); + } +} diff --git a/test/transform/resource/after-ecj/BuilderOnNestedRecord.java b/test/transform/resource/after-ecj/BuilderOnNestedRecord.java new file mode 100644 index 00000000..4e025485 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderOnNestedRecord.java @@ -0,0 +1,30 @@ +public record BuilderOnNestedRecord(T t) { + public @lombok.Builder record Nested(String a) { + public static @java.lang.SuppressWarnings("all") class NestedBuilder { + private @java.lang.SuppressWarnings("all") String a; + @java.lang.SuppressWarnings("all") NestedBuilder() { + super(); + } + /** + * @return {@code this}. + */ + public @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested.NestedBuilder a(final String a) { + this.a = a; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested build() { + return new BuilderOnNestedRecord.Nested(this.a); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderOnNestedRecord.Nested.NestedBuilder(a=" + this.a) + ")"); + } + } +/* Implicit */ private final String a; + + public static @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested.NestedBuilder builder() { + return new BuilderOnNestedRecord.Nested.NestedBuilder(); + } + } +/* Implicit */ private final T t; + +} diff --git a/test/transform/resource/after-ecj/WithOnNestedRecord.java b/test/transform/resource/after-ecj/WithOnNestedRecord.java new file mode 100644 index 00000000..6c68960b --- /dev/null +++ b/test/transform/resource/after-ecj/WithOnNestedRecord.java @@ -0,0 +1,23 @@ +import lombok.With; +public class WithOnNestedRecord { + public @With record Nested(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + + /** + * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed). + */ + public @java.lang.SuppressWarnings("all") WithOnNestedRecord.Nested withA(final String a) { + return ((this.a == a) ? this : new WithOnNestedRecord.Nested(a, this.b)); + } + /** + * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed). + */ + public @java.lang.SuppressWarnings("all") WithOnNestedRecord.Nested withB(final String b) { + return ((this.b == b) ? this : new WithOnNestedRecord.Nested(this.a, b)); + } + } + public WithOnNestedRecord() { + super(); + } +} diff --git a/test/transform/resource/before/BuilderOnNestedClass.java b/test/transform/resource/before/BuilderOnNestedClass.java new file mode 100644 index 00000000..741ac520 --- /dev/null +++ b/test/transform/resource/before/BuilderOnNestedClass.java @@ -0,0 +1,8 @@ +public class BuilderOnNestedClass { + private T t; + + @lombok.Builder + public static class Nested { + private String a; + } +} diff --git a/test/transform/resource/before/BuilderOnNestedRecord.java b/test/transform/resource/before/BuilderOnNestedRecord.java new file mode 100644 index 00000000..18a99962 --- /dev/null +++ b/test/transform/resource/before/BuilderOnNestedRecord.java @@ -0,0 +1,7 @@ +// version 14: +public record BuilderOnNestedRecord(T t) { + @lombok.Builder + public record Nested(String a) { + + } +} diff --git a/test/transform/resource/before/RecordNonNull b/test/transform/resource/before/RecordNonNull deleted file mode 100644 index e69de29b..00000000 diff --git a/test/transform/resource/before/WithOnNestedRecord.java b/test/transform/resource/before/WithOnNestedRecord.java new file mode 100644 index 00000000..8dc29202 --- /dev/null +++ b/test/transform/resource/before/WithOnNestedRecord.java @@ -0,0 +1,9 @@ +// version 14: +import lombok.With; + +public class WithOnNestedRecord { + @With + public record Nested(String a, String b) { + + } +} \ No newline at end of file From 27cd3e53aae4d3364eb089abfb1d5e1739e785fc Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 17 Dec 2023 13:35:55 +0100 Subject: [PATCH 15/65] Rework test to avoid diverging eclipse output If a record is part of a class some eclipse/ecj versions add the implicit static modifier to the output and some doesn't. If the record is nested in another record this doesn't happen. --- .../resource/after-delombok/WithOnNestedRecord.java | 2 +- test/transform/resource/after-ecj/WithOnNestedRecord.java | 5 +---- test/transform/resource/before/WithOnNestedRecord.java | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test/transform/resource/after-delombok/WithOnNestedRecord.java b/test/transform/resource/after-delombok/WithOnNestedRecord.java index 86c31ac6..89a75478 100644 --- a/test/transform/resource/after-delombok/WithOnNestedRecord.java +++ b/test/transform/resource/after-delombok/WithOnNestedRecord.java @@ -1,5 +1,5 @@ // version 14: -public class WithOnNestedRecord { +public record WithOnNestedRecord() { public record Nested(String a, String b) { /** diff --git a/test/transform/resource/after-ecj/WithOnNestedRecord.java b/test/transform/resource/after-ecj/WithOnNestedRecord.java index 6c68960b..a83ac94c 100644 --- a/test/transform/resource/after-ecj/WithOnNestedRecord.java +++ b/test/transform/resource/after-ecj/WithOnNestedRecord.java @@ -1,5 +1,5 @@ import lombok.With; -public class WithOnNestedRecord { +public record WithOnNestedRecord() { public @With record Nested(String a, String b) { /* Implicit */ private final String a; /* Implicit */ private final String b; @@ -17,7 +17,4 @@ public class WithOnNestedRecord { return ((this.b == b) ? this : new WithOnNestedRecord.Nested(this.a, b)); } } - public WithOnNestedRecord() { - super(); - } } diff --git a/test/transform/resource/before/WithOnNestedRecord.java b/test/transform/resource/before/WithOnNestedRecord.java index 8dc29202..d8d28f35 100644 --- a/test/transform/resource/before/WithOnNestedRecord.java +++ b/test/transform/resource/before/WithOnNestedRecord.java @@ -1,7 +1,7 @@ // version 14: import lombok.With; -public class WithOnNestedRecord { +public record WithOnNestedRecord() { @With public record Nested(String a, String b) { From 3d9018a4789d2903f389e164545ffc8adbca0e2d Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Tue, 19 Dec 2023 01:32:11 -0500 Subject: [PATCH 16/65] Update authors file Signed-off-by: Rob Stryker --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index bbbebb7c..a3e5fcf1 100755 --- a/AUTHORS +++ b/AUTHORS @@ -41,6 +41,7 @@ Pim van der Loos Rabea Gransberger Raul Wißfeld Reinier Zwitserloot +Rob Stryker Robbert Jan Grootjans Robert Wertman Roel Spilker From b6dd48a0422e09e297604ecca3f1bbb9497337ac Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 5 Jan 2024 14:56:39 +0100 Subject: [PATCH 17/65] [fixes #1443] Handle field initializer in diet mode --- .../eclipse/handlers/EclipseHandlerUtil.java | 39 +++++++- .../lombok/eclipse/handlers/HandleLocked.java | 18 +++- .../eclipse/handlers/HandleLockedRead.java | 18 +++- .../eclipse/handlers/HandleLockedWrite.java | 18 +++- .../eclipse/handlers/HandleSneakyThrows.java | 30 ++++-- .../eclipse/handlers/HandleSynchronized.java | 9 +- test/core/src/lombok/AbstractRunTests.java | 35 ++++--- test/core/src/lombok/LombokTestSource.java | 14 ++- test/core/src/lombok/RunTestsViaDelombok.java | 21 +++-- test/core/src/lombok/RunTestsViaEcj.java | 65 +++++++------ test/core/src/lombok/TestParameters.java | 94 +++++++++++++++++++ .../core/src/lombok/TransformationResult.java | 65 +++++++++++++ .../after-delombok/LockedInInitializer.java | 41 ++++++++ .../SneakyThrowsInInitializer.java | 12 +++ .../SynchronizedInInitializer.java | 12 +++ .../after-ecj/LockedInInitializer.java | 49 ++++++++++ .../after-ecj/SneakyThrowsInInitializer.java | 19 ++++ .../after-ecj/SynchronizedInInitializer.java | 16 ++++ .../resource/before/LockedInInitializer.java | 26 +++++ .../before/SneakyThrowsInInitializer.java | 15 +++ .../before/SynchronizedInInitializer.java | 12 +++ 21 files changed, 553 insertions(+), 75 deletions(-) create mode 100644 test/core/src/lombok/TestParameters.java create mode 100644 test/core/src/lombok/TransformationResult.java create mode 100644 test/transform/resource/after-delombok/LockedInInitializer.java create mode 100644 test/transform/resource/after-delombok/SneakyThrowsInInitializer.java create mode 100644 test/transform/resource/after-delombok/SynchronizedInInitializer.java create mode 100644 test/transform/resource/after-ecj/LockedInInitializer.java create mode 100644 test/transform/resource/after-ecj/SneakyThrowsInInitializer.java create mode 100644 test/transform/resource/after-ecj/SynchronizedInInitializer.java create mode 100644 test/transform/resource/before/LockedInInitializer.java create mode 100644 test/transform/resource/before/SneakyThrowsInInitializer.java create mode 100644 test/transform/resource/before/SynchronizedInInitializer.java diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index dd646e57..9411b9ba 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2022 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -2972,4 +2972,41 @@ public class EclipseHandlerUtil { setDocComment(cud, type, to, newJavadoc); } catch (Exception ignore) {} } + + /** + * Returns the method node containing the given annotation, or {@code null} if the given annotation node is not on a method or argument. + */ + public static EclipseNode getAnnotatedMethod(EclipseNode node) { + if (node == null || node.getKind() != Kind.ANNOTATION) return null; + + EclipseNode result = node.up(); + if (result.getKind() == Kind.ARGUMENT) { + result = node.up(); + } + if (result.getKind() != Kind.METHOD) { + result = null; + } + return result; + } + + /** + * Returns {@code true} if the given method node body was parsed. + */ + public static boolean hasParsedBody(EclipseNode method) { + if (method == null || method.getKind() != Kind.METHOD) return false; + + boolean isCompleteParse = method.getAst().isCompleteParse(); + if (isCompleteParse) return true; + + AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) method.get(); + if (methodDecl.statements != null) return true; + + // If the method is part of a field initializer it was parsed + EclipseNode parent = method.up(); + while (parent != null) { + if (parent.getKind() == Kind.FIELD) return true; + parent = parent.up(); + } + return false; + } } diff --git a/src/core/lombok/eclipse/handlers/HandleLocked.java b/src/core/lombok/eclipse/handlers/HandleLocked.java index 240a6498..ab733c97 100644 --- a/src/core/lombok/eclipse/handlers/HandleLocked.java +++ b/src/core/lombok/eclipse/handlers/HandleLocked.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 The Project Lombok Authors. + * Copyright (C) 2021-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,15 +21,19 @@ */ package lombok.eclipse.handlers; +import static lombok.eclipse.EcjAugments.ASTNode_handled; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; + +import lombok.Locked; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; -import lombok.Locked; import lombok.spi.Provides; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; /** * Handles the {@code lombok.Locked} annotation for eclipse. @@ -52,5 +56,11 @@ public class HandleLocked extends EclipseAnnotationHandler { @Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { String annotationValue = annotation.getInstance().value(); HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode); + + if (hasParsedBody(getAnnotatedMethod(annotationNode))) { + // This method has a body in diet mode, so we have to handle it now. + handle(annotation, source, annotationNode); + ASTNode_handled.set(source, true); + } } } diff --git a/src/core/lombok/eclipse/handlers/HandleLockedRead.java b/src/core/lombok/eclipse/handlers/HandleLockedRead.java index a293467a..33f2583b 100644 --- a/src/core/lombok/eclipse/handlers/HandleLockedRead.java +++ b/src/core/lombok/eclipse/handlers/HandleLockedRead.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 The Project Lombok Authors. + * Copyright (C) 2021-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,15 +21,19 @@ */ package lombok.eclipse.handlers; +import static lombok.eclipse.EcjAugments.ASTNode_handled; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; + +import lombok.Locked; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; -import lombok.Locked; import lombok.spi.Provides; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; /** * Handles the {@code lombok.Locked.Read} annotation for eclipse. @@ -53,5 +57,11 @@ public class HandleLockedRead extends EclipseAnnotationHandler { @Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { String annotationValue = annotation.getInstance().value(); HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode); + + if (hasParsedBody(getAnnotatedMethod(annotationNode))) { + // This method has a body in diet mode, so we have to handle it now. + handle(annotation, source, annotationNode); + ASTNode_handled.set(source, true); + } } } diff --git a/src/core/lombok/eclipse/handlers/HandleLockedWrite.java b/src/core/lombok/eclipse/handlers/HandleLockedWrite.java index 6192c76b..548b4d4a 100644 --- a/src/core/lombok/eclipse/handlers/HandleLockedWrite.java +++ b/src/core/lombok/eclipse/handlers/HandleLockedWrite.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 The Project Lombok Authors. + * Copyright (C) 2021-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,15 +21,19 @@ */ package lombok.eclipse.handlers; +import static lombok.eclipse.EcjAugments.ASTNode_handled; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; + +import lombok.Locked; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; -import lombok.Locked; import lombok.spi.Provides; -import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; /** * Handles the {@code lombok.Locked.Write} annotation for eclipse. @@ -53,5 +57,11 @@ public class HandleLockedWrite extends EclipseAnnotationHandler { @Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { String annotationValue = annotation.getInstance().value(); HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode); + + if (hasParsedBody(getAnnotatedMethod(annotationNode))) { + // This method has a body in diet mode, so we have to handle it now. + handle(annotation, source, annotationNode); + ASTNode_handled.set(source, true); + } } } diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java index 5f0ca3fb..74d9df6f 100644 --- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2021 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -22,6 +22,7 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.*; +import static lombok.eclipse.EcjAugments.ASTNode_handled; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Modifier; @@ -29,15 +30,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import lombok.ConfigurationKeys; -import lombok.SneakyThrows; -import lombok.core.AnnotationValues; -import lombok.core.HandlerPriority; -import lombok.eclipse.DeferUntilPostDiet; -import lombok.eclipse.EclipseAnnotationHandler; -import lombok.eclipse.EclipseNode; -import lombok.spi.Provides; - import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; @@ -58,6 +50,15 @@ import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; import org.eclipse.jdt.internal.compiler.ast.TryStatement; import org.eclipse.jdt.internal.compiler.ast.TypeReference; +import lombok.ConfigurationKeys; +import lombok.SneakyThrows; +import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; +import lombok.eclipse.DeferUntilPostDiet; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; +import lombok.spi.Provides; + /** * Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse. */ @@ -76,6 +77,15 @@ public class HandleSneakyThrows extends EclipseAnnotationHandler { } } + @Override + public void preHandle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { + if (hasParsedBody(getAnnotatedMethod(annotationNode))) { + // This method has a body in diet mode, so we have to handle it now. + handle(annotation, ast, annotationNode); + ASTNode_handled.set(ast, true); + } + } + @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.SNEAKY_THROWS_FLAG_USAGE, "@SneakyThrows"); diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index dbe363d9..c5fbcf4f 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2021 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -22,6 +22,7 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.*; +import static lombok.eclipse.EcjAugments.ASTNode_handled; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Modifier; @@ -70,6 +71,12 @@ public class HandleSynchronized extends EclipseAnnotationHandler { if (method.isAbstract()) return; createLockField(annotation, annotationNode, new boolean[] {method.isStatic()}, false); + + if (hasParsedBody(getAnnotatedMethod(annotationNode))) { + // This method has a body in diet mode, so we have to handle it now. + handle(annotation, source, annotationNode); + ASTNode_handled.set(source, true); + } } public char[] createLockField(AnnotationValues annotation, EclipseNode annotationNode, boolean[] isStatic, boolean reportErrors) { diff --git a/test/core/src/lombok/AbstractRunTests.java b/test/core/src/lombok/AbstractRunTests.java index 51ec41c5..0cb379ff 100644 --- a/test/core/src/lombok/AbstractRunTests.java +++ b/test/core/src/lombok/AbstractRunTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2018 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -29,14 +29,12 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; -import java.io.StringWriter; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import org.junit.Assert; @@ -83,28 +81,38 @@ public abstract class AbstractRunTests { return new FileTester() { @Override public void runTest() throws Throwable { if (directiveFailure_ != null) throw directiveFailure_; - LinkedHashSet messages = new LinkedHashSet(); - StringWriter writer = new StringWriter(); - LombokConfiguration.overrideConfigurationResolverFactory(new ConfigurationResolverFactory() { @Override public ConfigurationResolver createResolver(URI sourceLocation) { return sourceDirectives_.getConfiguration(); } }); + TestParameters testParameters = new TestParameters(); + testParameters.setEncoding(sourceDirectives_.getSpecifiedEncoding()); + testParameters.setFormatPreferences(sourceDirectives_.getFormatPreferences()); + testParameters.setMinVersion(sourceDirectives_.minVersion()); + testParameters.setVerifyDiet(sourceDirectives_.isVerifyDiet()); boolean checkPositions = !(params instanceof TestLombokFilesIdempotent || params instanceof TestSourceFiles) && !sourceDirectives_.isSkipCompareContent(); + testParameters.setCheckPositions(checkPositions); + String javaVersionString = System.getProperty("compiler.compliance.level"); + if (javaVersionString != null) { + long version = Long.parseLong(javaVersionString); + testParameters.setSourceVersion(version); + testParameters.setTargetVersion(version); + } - boolean changed = transformCode(messages, writer, file, sourceDirectives_.getSpecifiedEncoding(), sourceDirectives_.getFormatPreferences(), sourceDirectives_.minVersion(), checkPositions); + TransformationResult result = transformCode(file, testParameters); + boolean changed = result.isChanged(); boolean forceUnchanged = sourceDirectives_.forceUnchanged() || sourceDirectives_.isSkipCompareContent(); - if (params.expectChanges() && !forceUnchanged && !changed) messages.add(new CompilerMessage(-1, -1, true, "not flagged modified")); - if (!params.expectChanges() && changed) messages.add(new CompilerMessage(-1, -1, true, "unexpected modification")); + if (params.expectChanges() && !forceUnchanged && !changed) result.addMessage(new CompilerMessage(-1, -1, true, "not flagged modified")); + if (!params.expectChanges() && changed) result.addMessage(new CompilerMessage(-1, -1, true, "unexpected modification")); - compare(file.getName(), expected, writer.toString(), messages, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent()); + compare(file.getName(), expected, result, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent()); } }; } - protected abstract boolean transformCode(Collection messages, StringWriter result, File file, String encoding, Map formatPreferences, int minVersion, boolean checkPositions) throws Throwable; + protected abstract TransformationResult transformCode(File file, TestParameters parameters) throws Throwable; protected String readFile(File file) throws IOException { BufferedReader reader; @@ -154,7 +162,10 @@ public abstract class AbstractRunTests { } } - private void compare(String name, LombokTestSource expected, String actualFile, LinkedHashSet actualMessages, boolean printErrors, boolean skipCompareContent) throws Throwable { + private void compare(String name, LombokTestSource expected, TransformationResult result, boolean printErrors, boolean skipCompareContent) throws Throwable { + String actualFile = result.getOutput(); + LinkedHashSet actualMessages = result.getMessages(); + if (!skipCompareContent) try { compareContent(name, expected.getContent(), actualFile); } catch (Throwable e) { diff --git a/test/core/src/lombok/LombokTestSource.java b/test/core/src/lombok/LombokTestSource.java index 27ffc31a..92bc53ea 100644 --- a/test/core/src/lombok/LombokTestSource.java +++ b/test/core/src/lombok/LombokTestSource.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2019 The Project Lombok Authors. + * Copyright (C) 2014-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 @@ -58,6 +58,7 @@ public class LombokTestSource { private final boolean skipCompareContent; private final boolean skipIdempotent; private final boolean unchanged; + private final boolean verifyDiet; private final int versionLowerLimit, versionUpperLimit; private final ConfigurationResolver configuration; private final String specifiedEncoding; @@ -113,6 +114,10 @@ public class LombokTestSource { return skipIdempotent; } + public boolean isVerifyDiet() { + return verifyDiet; + } + public String getSpecifiedEncoding() { return specifiedEncoding; } @@ -162,6 +167,7 @@ public class LombokTestSource { private static final Pattern SKIP_COMPARE_CONTENT_PATTERN = Pattern.compile("^\\s*skip[- ]?compare[- ]?contents?\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE); private static final Pattern SKIP_IDEMPOTENT_PATTERN = Pattern.compile("^\\s*skip[- ]?idempotent\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE); private static final Pattern ISSUE_REF_PATTERN = Pattern.compile("^\\s*issue #?\\d+(:?\\s+.*)?$", Pattern.CASE_INSENSITIVE); + private static final Pattern VERIFY_DIET_PATTERN = Pattern.compile("^\\s*eclipse:\\s*verify[- ]?diet\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE); private LombokTestSource(File file, String content, List messages, List directives) { this.file = file; @@ -175,6 +181,7 @@ public class LombokTestSource { boolean skipCompareContent = false; boolean skipIdempotent = false; boolean unchanged = false; + boolean verifyDiet = false; String encoding = null; Map formats = new HashMap(); String[] platformLimit = null; @@ -204,6 +211,10 @@ public class LombokTestSource { if (ISSUE_REF_PATTERN.matcher(directive).matches()) { continue; } + if (VERIFY_DIET_PATTERN.matcher(directive).matches()) { + verifyDiet = true; + continue; + } if (lc.startsWith("platform ")) { String platformDesc = lc.substring("platform ".length()); @@ -257,6 +268,7 @@ public class LombokTestSource { this.skipCompareContent = skipCompareContent; this.skipIdempotent = skipIdempotent; this.unchanged = unchanged; + this.verifyDiet = verifyDiet; this.platforms = platformLimit == null ? null : Arrays.asList(platformLimit); ConfigurationProblemReporter reporter = new ConfigurationProblemReporter() { diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java index adfb1fce..918a0de4 100644 --- a/test/core/src/lombok/RunTestsViaDelombok.java +++ b/test/core/src/lombok/RunTestsViaDelombok.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2021 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -66,24 +66,24 @@ import com.sun.tools.javac.tree.TreeScanner; import lombok.delombok.Delombok; import lombok.javac.CapturingDiagnosticListener; -import lombok.javac.CapturingDiagnosticListener.CompilerMessage; import lombok.javac.Javac; public class RunTestsViaDelombok extends AbstractRunTests { private Delombok delombok = new Delombok(); @Override - public boolean transformCode(Collection messages, StringWriter result, final File file, String encoding, Map formatPreferences, int version, boolean checkPositions) throws Throwable { + public TransformationResult transformCode(final File file, TestParameters parameters) throws Throwable { + TransformationResult result = new TransformationResult(); delombok.setVerbose(true); ChangedChecker cc = new ChangedChecker(); delombok.setFeedback(cc.feedback); delombok.setForceProcess(true); - delombok.setCharset(encoding == null ? "UTF-8" : encoding); - delombok.setFormatPreferences(formatPreferences); + delombok.setCharset(parameters.getEncoding() == null ? "UTF-8" : parameters.getEncoding()); + delombok.setFormatPreferences(parameters.getFormatPreferences()); - delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, messages)); + delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, result.getMessages())); - if (checkPositions) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(version)); + if (parameters.isCheckPositions()) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion())); delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor()); delombok.addAdditionalAnnotationProcessor(new ValidateNoDuplicateTreeNodeProcessor()); @@ -91,12 +91,15 @@ public class RunTestsViaDelombok extends AbstractRunTests { delombok.setSourcepath(file.getAbsoluteFile().getParent()); String bcp = System.getProperty("delombok.bootclasspath"); if (bcp != null) delombok.setBootclasspath(bcp); - delombok.setWriter(result); + StringWriter sw = new StringWriter(); + delombok.setWriter(sw); Locale originalLocale = Locale.getDefault(); try { Locale.setDefault(Locale.ENGLISH); delombok.delombok(); - return cc.isChanged(); + result.setOutput(sw.toString()); + result.setChanged(cc.isChanged()); + return result; } finally { Locale.setDefault(originalLocale); } diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index d46a890f..57174947 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.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 @@ -22,9 +22,7 @@ package lombok; import java.io.File; -import java.io.StringWriter; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -32,9 +30,6 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import lombok.eclipse.Eclipse; -import lombok.javac.CapturingDiagnosticListener.CompilerMessage; - import org.eclipse.core.internal.registry.ExtensionRegistry; import org.eclipse.core.internal.runtime.Activator; import org.eclipse.core.internal.runtime.PlatformActivator; @@ -61,18 +56,19 @@ import org.eclipse.jdt.internal.core.JavaModelManager; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import lombok.eclipse.Eclipse; +import lombok.javac.CapturingDiagnosticListener.CompilerMessage; + public class RunTestsViaEcj extends AbstractRunTests { - protected CompilerOptions ecjCompilerOptions() { + protected CompilerOptions ecjCompilerOptions(TestParameters parameters) { CompilerOptions options = new CompilerOptions(); Map warnings = new HashMap(); - String javaVersionString = System.getProperty("compiler.compliance.level"); long ecjCompilerVersionConstant = Eclipse.getLatestEcjCompilerVersionConstant(); long ecjCompilerVersion = Eclipse.getEcjCompilerVersion(); - if (javaVersionString != null) { - long javaVersion = Long.parseLong(javaVersionString); - ecjCompilerVersionConstant = (javaVersion + 44) << 16; - ecjCompilerVersion = javaVersion; + if (parameters.getSourceVersion() != null) { + ecjCompilerVersionConstant = (parameters.getSourceVersion() + 44) << 16; + ecjCompilerVersion = parameters.getSourceVersion(); } else { // Preview features are only allowed if the maximum compiler version is equal to the source version warnings.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled"); @@ -127,7 +123,8 @@ public class RunTestsViaEcj extends AbstractRunTests { } @Override - public boolean transformCode(Collection messages, StringWriter result, File file, String encoding, Map formatPreferences, int minVersion, boolean checkPositions) throws Throwable { + public TransformationResult transformCode(File file, TestParameters parameters) throws Throwable { + TransformationResult result = new TransformationResult(); final AtomicReference compilationResult_ = new AtomicReference(); final AtomicReference compilationUnit_ = new AtomicReference(); ICompilerRequestor bitbucketRequestor = new ICompilerRequestor() { @@ -143,12 +140,18 @@ public class RunTestsViaEcj extends AbstractRunTests { sourceUnit = getSourceUnit(file, source); } catch (Throwable t) { t.printStackTrace(); - return false; + result.setChanged(false); + return result; } - Compiler ecjCompiler = new Compiler(createFileSystem(file, minVersion), ecjErrorHandlingPolicy(), ecjCompilerOptions(), bitbucketRequestor, new DefaultProblemFactory(Locale.ENGLISH)) { + Compiler ecjCompiler = new Compiler(createFileSystem(file), ecjErrorHandlingPolicy(), ecjCompilerOptions(parameters), bitbucketRequestor, new DefaultProblemFactory(Locale.ENGLISH)) { @Override protected synchronized void addCompilationUnit(ICompilationUnit inUnit, CompilationUnitDeclaration parsedUnit) { - if (inUnit == sourceUnit) compilationUnit_.set(parsedUnit); + if (inUnit == sourceUnit) { + compilationUnit_.set(parsedUnit); + if (parameters.isVerifyDiet()) { + result.setOutput(parsedUnit.toString()); + } + } super.addCompilationUnit(inUnit, parsedUnit); } }; @@ -161,24 +164,28 @@ public class RunTestsViaEcj extends AbstractRunTests { CategorizedProblem[] problems = compilationResult.getAllProblems(); if (problems != null) for (CategorizedProblem p : problems) { - messages.add(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.isError(), p.getMessage())); + result.addMessage(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.isError(), p.getMessage())); } CompilationUnitDeclaration cud = compilationUnit_.get(); - if (cud == null) result.append("---- No CompilationUnit provided by ecj ----"); - else { - String output = cud.toString(); - // starting somewhere around ecj16, the print code is a bit too cavalier with printing modifiers. - output = output.replace("non-sealed @val", "@val"); - result.append(output); + if (cud == null) { + result.setOutput("---- No CompilationUnit provided by ecj ----"); + } else { + if (!parameters.isVerifyDiet()) { + String output = cud.toString(); + // starting somewhere around ecj16, the print code is a bit too cavalier with printing modifiers. + output = output.replace("non-sealed @val", "@val"); + result.setOutput(output); + } + + if (eclipseAvailable()) { + EclipseDomConversion.toDomAst(cud, sourceArray); + } } - if (eclipseAvailable()) { - EclipseDomConversion.toDomAst(cud, sourceArray); - } - - return true; + result.setChanged(true); + return result; } @SuppressWarnings("unused") @@ -238,7 +245,7 @@ public class RunTestsViaEcj extends AbstractRunTests { } } - private FileSystem createFileSystem(File file, int minVersion) { + private FileSystem createFileSystem(File file) { List classpath = new ArrayList(); if (new File("bin/main").exists()) classpath.add("bin/main"); classpath.add("dist/lombok.jar"); diff --git a/test/core/src/lombok/TestParameters.java b/test/core/src/lombok/TestParameters.java new file mode 100644 index 00000000..dba7b990 --- /dev/null +++ b/test/core/src/lombok/TestParameters.java @@ -0,0 +1,94 @@ +/* + * 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; + +import java.util.Map; + +public class TestParameters { + private Long sourceVersion; + private Long targetVersion; + + // Javac only + private Integer minVersion; + private String encoding; + private Map formatPreferences; + private boolean checkPositions; + + // Eclipse/Ecj only + private boolean verifyDiet; + + public Long getSourceVersion() { + return sourceVersion; + } + + public void setSourceVersion(Long sourceVersion) { + this.sourceVersion = sourceVersion; + } + + public Long getTargetVersion() { + return targetVersion; + } + + public void setTargetVersion(Long targetVersion) { + this.targetVersion = targetVersion; + } + + public Integer getMinVersion() { + return minVersion; + } + + public void setMinVersion(Integer minVersion) { + this.minVersion = minVersion; + } + + public String getEncoding() { + return encoding; + } + + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + public Map getFormatPreferences() { + return formatPreferences; + } + + public void setFormatPreferences(Map formatPreferences) { + this.formatPreferences = formatPreferences; + } + + public boolean isCheckPositions() { + return checkPositions; + } + + public void setCheckPositions(boolean checkPositions) { + this.checkPositions = checkPositions; + } + + public boolean isVerifyDiet() { + return verifyDiet; + } + + public void setVerifyDiet(boolean verifyDiet) { + this.verifyDiet = verifyDiet; + } +} diff --git a/test/core/src/lombok/TransformationResult.java b/test/core/src/lombok/TransformationResult.java new file mode 100644 index 00000000..b0d45e44 --- /dev/null +++ b/test/core/src/lombok/TransformationResult.java @@ -0,0 +1,65 @@ +/* + * 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; + +import java.util.LinkedHashSet; + +import lombok.javac.CapturingDiagnosticListener.CompilerMessage; + +public class TransformationResult { + private boolean changed; + private boolean success; + private LinkedHashSet messages = new LinkedHashSet(); + private String output; + + public void addMessage(CompilerMessage message) { + getMessages().add(message); + } + + public void setOutput(String output) { + this.output = output; + } + + public String getOutput() { + return output; + } + + public boolean isChanged() { + return changed; + } + + public void setChanged(boolean changed) { + this.changed = changed; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public LinkedHashSet getMessages() { + return messages; + } +} diff --git a/test/transform/resource/after-delombok/LockedInInitializer.java b/test/transform/resource/after-delombok/LockedInInitializer.java new file mode 100644 index 00000000..a4b687fc --- /dev/null +++ b/test/transform/resource/after-delombok/LockedInInitializer.java @@ -0,0 +1,41 @@ +public class LockedInInitializer { + public static final Runnable LOCKED = new Runnable() { + @java.lang.SuppressWarnings("all") + private final java.util.concurrent.locks.Lock $lock = new java.util.concurrent.locks.ReentrantLock(); + @Override + public void run() { + this.$lock.lock(); + try { + System.out.println("test"); + } finally { + this.$lock.unlock(); + } + } + }; + public static final Runnable LOCKED_READ = new Runnable() { + @java.lang.SuppressWarnings("all") + private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock(); + @Override + public void run() { + this.$lock.readLock().lock(); + try { + System.out.println("test"); + } finally { + this.$lock.readLock().unlock(); + } + } + }; + public static final Runnable LOCKED_WRITE = new Runnable() { + @java.lang.SuppressWarnings("all") + private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock(); + @Override + public void run() { + this.$lock.writeLock().lock(); + try { + System.out.println("test"); + } finally { + this.$lock.writeLock().unlock(); + } + } + }; +} diff --git a/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java b/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java new file mode 100644 index 00000000..b47dadc4 --- /dev/null +++ b/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java @@ -0,0 +1,12 @@ +public class SneakyThrowsInInitializer { + public static final Runnable R = new Runnable() { + @Override + public void run() { + try { + System.out.println("test"); + } catch (final java.lang.Throwable $ex) { + throw lombok.Lombok.sneakyThrow($ex); + } + } + }; +} diff --git a/test/transform/resource/after-delombok/SynchronizedInInitializer.java b/test/transform/resource/after-delombok/SynchronizedInInitializer.java new file mode 100644 index 00000000..c63f4e74 --- /dev/null +++ b/test/transform/resource/after-delombok/SynchronizedInInitializer.java @@ -0,0 +1,12 @@ +public class SynchronizedInInitializer { + public static final Runnable SYNCHRONIZED = new Runnable() { + @java.lang.SuppressWarnings("all") + private final java.lang.Object $lock = new java.lang.Object[0]; + @Override + public void run() { + synchronized (this.$lock) { + System.out.println("test"); + } + } + }; +} diff --git a/test/transform/resource/after-ecj/LockedInInitializer.java b/test/transform/resource/after-ecj/LockedInInitializer.java new file mode 100644 index 00000000..aea88d0d --- /dev/null +++ b/test/transform/resource/after-ecj/LockedInInitializer.java @@ -0,0 +1,49 @@ +import lombok.Locked; +public class LockedInInitializer { + public static final Runnable LOCKED = new Runnable() { + private final java.util.concurrent.locks.Lock $lock = new java.util.concurrent.locks.ReentrantLock(); + public @Override @Locked void run() { + this.$lock.lock(); + try + { + System.out.println("test"); + } + finally + { + this.$lock.unlock(); + } + } + }; + public static final Runnable LOCKED_READ = new Runnable() { + private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock(); + public @Override @Locked.Read void run() { + this.$lock.readLock().lock(); + try + { + System.out.println("test"); + } + finally + { + this.$lock.readLock().unlock(); + } + } + }; + public static final Runnable LOCKED_WRITE = new Runnable() { + private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock(); + public @Override @Locked.Write void run() { + this.$lock.writeLock().lock(); + try + { + System.out.println("test"); + } + finally + { + this.$lock.writeLock().unlock(); + } + } + }; + () { + } + public LockedInInitializer() { + } +} diff --git a/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java b/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java new file mode 100644 index 00000000..2e981b02 --- /dev/null +++ b/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java @@ -0,0 +1,19 @@ +import lombok.SneakyThrows; +public class SneakyThrowsInInitializer { + public static final Runnable R = new Runnable() { + public @Override @SneakyThrows void run() { + try + { + System.out.println("test"); + } + catch (final java.lang.Throwable $ex) + { + throw lombok.Lombok.sneakyThrow($ex); + } + } + }; + () { + } + public SneakyThrowsInInitializer() { + } +} diff --git a/test/transform/resource/after-ecj/SynchronizedInInitializer.java b/test/transform/resource/after-ecj/SynchronizedInInitializer.java new file mode 100644 index 00000000..dad6ff8d --- /dev/null +++ b/test/transform/resource/after-ecj/SynchronizedInInitializer.java @@ -0,0 +1,16 @@ +import lombok.Synchronized; +public class SynchronizedInInitializer { + public static final Runnable SYNCHRONIZED = new Runnable() { + private final java.lang.Object $lock = new java.lang.Object[0]; + public @Override @Synchronized void run() { + synchronized (this.$lock) + { + System.out.println("test"); + } + } + }; + () { + } + public SynchronizedInInitializer() { + } +} diff --git a/test/transform/resource/before/LockedInInitializer.java b/test/transform/resource/before/LockedInInitializer.java new file mode 100644 index 00000000..f4df0247 --- /dev/null +++ b/test/transform/resource/before/LockedInInitializer.java @@ -0,0 +1,26 @@ +//eclipse: verify diet +import lombok.Locked; + +public class LockedInInitializer { + public static final Runnable LOCKED = new Runnable() { + @Override + @Locked + public void run() { + System.out.println("test"); + } + }; + public static final Runnable LOCKED_READ = new Runnable() { + @Override + @Locked.Read + public void run() { + System.out.println("test"); + } + }; + public static final Runnable LOCKED_WRITE = new Runnable() { + @Override + @Locked.Write + public void run() { + System.out.println("test"); + } + }; +} \ No newline at end of file diff --git a/test/transform/resource/before/SneakyThrowsInInitializer.java b/test/transform/resource/before/SneakyThrowsInInitializer.java new file mode 100644 index 00000000..87f77309 --- /dev/null +++ b/test/transform/resource/before/SneakyThrowsInInitializer.java @@ -0,0 +1,15 @@ +//eclipse: verify diet +import lombok.SneakyThrows; + +public class SneakyThrowsInInitializer { + + public static final Runnable R = new Runnable() { + + @Override + @SneakyThrows + public void run() { + System.out.println("test"); + + } + }; +} diff --git a/test/transform/resource/before/SynchronizedInInitializer.java b/test/transform/resource/before/SynchronizedInInitializer.java new file mode 100644 index 00000000..4d295d9e --- /dev/null +++ b/test/transform/resource/before/SynchronizedInInitializer.java @@ -0,0 +1,12 @@ +//eclipse: verify diet +import lombok.Synchronized; + +public class SynchronizedInInitializer { + public static final Runnable SYNCHRONIZED = new Runnable() { + @Override + @Synchronized + public void run() { + System.out.println("test"); + } + }; +} \ No newline at end of file From a31ff3bf68dca15949899c3981965a6d20dc0323 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 5 Jan 2024 15:30:42 +0100 Subject: [PATCH 18/65] Fix test class compilation error --- test/core/src/lombok/RunTestsViaEcj.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index 57174947..8e9369e7 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.java @@ -123,8 +123,8 @@ public class RunTestsViaEcj extends AbstractRunTests { } @Override - public TransformationResult transformCode(File file, TestParameters parameters) throws Throwable { - TransformationResult result = new TransformationResult(); + public TransformationResult transformCode(File file, final TestParameters parameters) throws Throwable { + final TransformationResult result = new TransformationResult(); final AtomicReference compilationResult_ = new AtomicReference(); final AtomicReference compilationUnit_ = new AtomicReference(); ICompilerRequestor bitbucketRequestor = new ICompilerRequestor() { From 84cb36d25cdd837e368b8654d5465e360537d131 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 00:17:05 +0100 Subject: [PATCH 19/65] [website] Further clarified the interaction between `@Builder` and `@NoArgsConstructor` in the builder docs, as an update to previous commit --- website/templates/features/Builder.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html index b7a4f2e2..05881083 100644 --- a/website/templates/features/Builder.html +++ b/website/templates/features/Builder.html @@ -66,7 +66,7 @@

Now that the "method" mode is clear, putting a @Builder annotation on a constructor functions similarly; effectively, constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their type parameters are the same as the type parameters of the class itself.

- Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself or created one with @NoArgsConstructor. If you do have an explicit constructor, put the @Builder annotation on the constructor instead of on the class. Note that if you put both `@Value` and `@Builder` on a class, the package-private constructor that `@Builder` wants to generate 'wins' and suppresses the constructor that `@Value` wants to make. + Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself or allowed lombok to create one such as with @NoArgsConstructor. If you do have an explicit constructor, put the @Builder annotation on the constructor instead of on the class. Note that if you put both `@Value` and `@Builder` on a class, the package-private constructor that `@Builder` wants to generate 'wins' and suppresses the constructor that `@Value` wants to make.

If using @Builder to generate builders to produce instances of your own class (this is always the case unless adding @Builder to a method that doesn't return your own type), you can use @Builder(toBuilder = true) to also generate an instance method in your class called toBuilder(); it creates a new builder that starts out with all the values of this instance. You can put the @Builder.ObtainVia annotation on the parameters (in case of a constructor or method) or fields (in case of @Builder on a type) to indicate alternative means by which the value for that field/parameter is obtained from this instance. For example, you can specify a method to be invoked: @Builder.ObtainVia(method = "calculateFoo").

From f704aba40d7a18edbd21c71f220bcc88f12b2809 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 00:26:46 +0100 Subject: [PATCH 20/65] [trivial] style --- src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 1616d956..4d658516 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -985,7 +985,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "getHTMLContentFromSource", "java.lang.String", "java.lang.String", "org.eclipse.jdt.core.IJavaElement")) .requestExtra(StackRequest.PARAM1) .build()); - + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField() .fieldName("$javadoc") .fieldType("Ljava/util/Map;") @@ -1043,7 +1043,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "printMethod", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration")) .requestExtra(StackRequest.THIS) .build()); - + sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.replaceMethodCall() .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer")) From e5e2e38f45f38773ecf61130b59b0e4c20836703 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 00:38:11 +0100 Subject: [PATCH 21/65] [changelog] [#3564] Update changelog to reflect eclipse StringBuffer/StringBuilder fix --- doc/changelog.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index d8828870..0b0802d7 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,6 +2,7 @@ Lombok Changelog ---------------- ### v1.18.31 "Edgy Guinea Pig" +* PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564). * FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506). * We recently released v1.18.30; there is no edge release since then. From 3114049cd3737a3ab81ec3659750731156f68474 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 00:20:23 +0100 Subject: [PATCH 22/65] [build] Update IvyPlusPlus req to minimum 1.42 --- buildScripts/setup.ant.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index 39954a02..f6329a3a 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -118,7 +118,7 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - + From 55f3a02909957f97c2496ef25135857bf27cdd36 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 00:53:27 +0100 Subject: [PATCH 23/65] [review] Split off POJOs modelling XML tags into its own package --- .../lombok/eclipse/dependencies/UniqueQueue.java | 2 +- .../lombok/eclipse/dependencies/UpdateSite.java | 6 ++++++ .../eclipse/dependencies/{ => model}/Child.java | 4 ++-- .../eclipse/dependencies/{ => model}/Provided.java | 8 ++++---- .../eclipse/dependencies/{ => model}/Repository.java | 6 +++--- .../eclipse/dependencies/{ => model}/Required.java | 12 ++++++------ .../eclipse/dependencies/{ => model}/Unit.java | 10 +++++----- 7 files changed, 27 insertions(+), 21 deletions(-) rename src/support/lombok/eclipse/dependencies/{ => model}/Child.java (55%) rename src/support/lombok/eclipse/dependencies/{ => model}/Provided.java (51%) rename src/support/lombok/eclipse/dependencies/{ => model}/Repository.java (77%) rename src/support/lombok/eclipse/dependencies/{ => model}/Required.java (54%) rename src/support/lombok/eclipse/dependencies/{ => model}/Unit.java (74%) diff --git a/src/support/lombok/eclipse/dependencies/UniqueQueue.java b/src/support/lombok/eclipse/dependencies/UniqueQueue.java index 7ec4a38c..6a97612e 100644 --- a/src/support/lombok/eclipse/dependencies/UniqueQueue.java +++ b/src/support/lombok/eclipse/dependencies/UniqueQueue.java @@ -5,7 +5,7 @@ import java.util.HashSet; import java.util.Set; /** - * A incomplete implementation of a queue that maintains a history of all queued items and ensures unique elements. + * An incomplete implementation of a queue that maintains a history of all queued items and ensures unique elements. * Elements cannot be added to the queue if they already exist in the history. */ public class UniqueQueue extends ArrayDeque { diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java index 93da4120..c3379361 100644 --- a/src/support/lombok/eclipse/dependencies/UpdateSite.java +++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java @@ -24,6 +24,12 @@ import javax.xml.transform.sax.SAXSource; import org.xml.sax.InputSource; +import lombok.eclipse.dependencies.model.Child; +import lombok.eclipse.dependencies.model.Provided; +import lombok.eclipse.dependencies.model.Repository; +import lombok.eclipse.dependencies.model.Required; +import lombok.eclipse.dependencies.model.Unit; + public class UpdateSite { private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); private static final String OSGI_OS = OS_NAME.contains("windows") ? "windows" : OS_NAME.contains("mac") ? "mac" : "linux"; diff --git a/src/support/lombok/eclipse/dependencies/Child.java b/src/support/lombok/eclipse/dependencies/model/Child.java similarity index 55% rename from src/support/lombok/eclipse/dependencies/Child.java rename to src/support/lombok/eclipse/dependencies/model/Child.java index 06b93793..818645e2 100644 --- a/src/support/lombok/eclipse/dependencies/Child.java +++ b/src/support/lombok/eclipse/dependencies/model/Child.java @@ -1,8 +1,8 @@ -package lombok.eclipse.dependencies; +package lombok.eclipse.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; public class Child { @XmlAttribute - String location; + public String location; } \ No newline at end of file diff --git a/src/support/lombok/eclipse/dependencies/Provided.java b/src/support/lombok/eclipse/dependencies/model/Provided.java similarity index 51% rename from src/support/lombok/eclipse/dependencies/Provided.java rename to src/support/lombok/eclipse/dependencies/model/Provided.java index 6ca7d6f3..b531d3e1 100644 --- a/src/support/lombok/eclipse/dependencies/Provided.java +++ b/src/support/lombok/eclipse/dependencies/model/Provided.java @@ -1,12 +1,12 @@ -package lombok.eclipse.dependencies; +package lombok.eclipse.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; public class Provided { @XmlAttribute - String namespace; + public String namespace; @XmlAttribute - String name; + public String name; @XmlAttribute - String version; + public String version; } diff --git a/src/support/lombok/eclipse/dependencies/Repository.java b/src/support/lombok/eclipse/dependencies/model/Repository.java similarity index 77% rename from src/support/lombok/eclipse/dependencies/Repository.java rename to src/support/lombok/eclipse/dependencies/model/Repository.java index 8423d7ee..1d81bf8c 100644 --- a/src/support/lombok/eclipse/dependencies/Repository.java +++ b/src/support/lombok/eclipse/dependencies/model/Repository.java @@ -1,4 +1,4 @@ -package lombok.eclipse.dependencies; +package lombok.eclipse.dependencies.model; import java.util.List; @@ -10,9 +10,9 @@ import javax.xml.bind.annotation.XmlRootElement; public class Repository { @XmlElementWrapper(name = "children") @XmlElement(name="child") - List children; + public List children; @XmlElementWrapper(name = "units") @XmlElement(name="unit") - List units; + public List units; } \ No newline at end of file diff --git a/src/support/lombok/eclipse/dependencies/Required.java b/src/support/lombok/eclipse/dependencies/model/Required.java similarity index 54% rename from src/support/lombok/eclipse/dependencies/Required.java rename to src/support/lombok/eclipse/dependencies/model/Required.java index 5f1f895d..36fbe46e 100644 --- a/src/support/lombok/eclipse/dependencies/Required.java +++ b/src/support/lombok/eclipse/dependencies/model/Required.java @@ -1,17 +1,17 @@ -package lombok.eclipse.dependencies; +package lombok.eclipse.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; public class Required { @XmlAttribute - String namespace; + public String namespace; @XmlAttribute - String name; + public String name; @XmlAttribute - String range; + public String range; @XmlAttribute - boolean optional; + public boolean optional; @XmlElement - String filter; + public String filter; } diff --git a/src/support/lombok/eclipse/dependencies/Unit.java b/src/support/lombok/eclipse/dependencies/model/Unit.java similarity index 74% rename from src/support/lombok/eclipse/dependencies/Unit.java rename to src/support/lombok/eclipse/dependencies/model/Unit.java index 51827cf0..82d7809e 100644 --- a/src/support/lombok/eclipse/dependencies/Unit.java +++ b/src/support/lombok/eclipse/dependencies/model/Unit.java @@ -1,4 +1,4 @@ -package lombok.eclipse.dependencies; +package lombok.eclipse.dependencies.model; import java.util.List; @@ -8,17 +8,17 @@ import javax.xml.bind.annotation.XmlElementWrapper; public class Unit { @XmlAttribute - String id; + public String id; @XmlAttribute - String version; + public String version; @XmlElementWrapper(name = "provides") @XmlElement(name="provided") - List provides; + public List provides; @XmlElementWrapper(name = "requires") @XmlElement(name="required") - List requires; + public List requires; @Override public String toString() { From 22a39a336bbd55e8470d94da0c7903326307193d Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:03:01 +0100 Subject: [PATCH 24/65] [changelog] [#3571] [#3497] Reflect fix of nested records in the changelog. --- doc/changelog.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 2ebf4a8a..83cf0fc5 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -4,6 +4,7 @@ Lombok Changelog ### v1.18.31 "Edgy Guinea Pig" * PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564). * FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506). +* BUGFIX: Many lombok features wouldn't work properly on records contained within an outer type unless you explicitly marked it `static`. [Issue #3497](https://github.com/projectlombok/lombok/issues/3497) [Issue #3559](https://github.com/projectlombok/lombok/issues/3559). * BUGFIX: Eclipse projects using the com.pro-crafting.tools:jasperreports-plugin will now compile * We recently released v1.18.30; there is no edge release since then. From 5a214701dbbf4cb3afc06677b47e1415d05dcb46 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:25:13 +0100 Subject: [PATCH 25/65] [changelog] It's aliiiiiiiiiiiiiiive! --- doc/changelog.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 83cf0fc5..4379eb96 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -4,6 +4,7 @@ Lombok Changelog ### v1.18.31 "Edgy Guinea Pig" * PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564). * FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506). +* NECROMANCY: Inlining a generated getter in eclipse would result in eclipse incorrectly replacing calls with `@Getter` instead of the actual field's name. [Issue #562](https://github.com/projectlombok/lombok/issues/562). This issue is almost old enough to drink. Points for dedication go to Rawi for fixing this one. * BUGFIX: Many lombok features wouldn't work properly on records contained within an outer type unless you explicitly marked it `static`. [Issue #3497](https://github.com/projectlombok/lombok/issues/3497) [Issue #3559](https://github.com/projectlombok/lombok/issues/3559). * BUGFIX: Eclipse projects using the com.pro-crafting.tools:jasperreports-plugin will now compile * We recently released v1.18.30; there is no edge release since then. From 4625adc6f760c56a9c9ac642a3a2eec3c9b93629 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:33:58 +0100 Subject: [PATCH 26/65] [integration-tests] Add java 22 --- .github/workflows/ant.yml | 12 ++++++------ buildScripts/ivy.xml | 2 +- docker/provision/jdk/java-22.sh | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 89d71dda..892b3fc6 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -42,7 +42,7 @@ jobs: needs: build strategy: matrix: - jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21] + jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22] goal: [javacCurrent] include: - jdk: 11 @@ -56,18 +56,18 @@ jobs: uses: actions/checkout@v3 - name: Set up JDK ${{ matrix.jdk }} - if: ${{ matrix.jdk != 21 }} + if: ${{ matrix.jdk < 21 }} uses: actions/setup-java@v3 with: java-version: ${{ matrix.jdk }} distribution: 'zulu' - - name: Set up JDK 21-ea - if: ${{ matrix.jdk == 21 }} + - name: Set up JDK 21 and up including Early Access releases + if: ${{ matrix.jdk >= 21 }} uses: oracle-actions/setup-java@v1 with: website: jdk.java.net - release: 21 + release: ${{ matrix.jdk }} version: latest - name: Install Ant @@ -156,7 +156,7 @@ jobs: needs: build strategy: matrix: - jdk: [8, 11, 17, 21] + jdk: [8, 11, 17, 21, 22] tool: - {name: "maven", cmd: "mvn compile"} - {name: "gradle", cmd: "gradle assemble"} diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index 6a5cd0eb..aa2643ed 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -38,7 +38,7 @@ - + diff --git a/docker/provision/jdk/java-22.sh b/docker/provision/jdk/java-22.sh index 08d8c00a..c442a6dc 100644 --- a/docker/provision/jdk/java-22.sh +++ b/docker/provision/jdk/java-22.sh @@ -1,4 +1,4 @@ apt-get update && apt-get install -y wget -wget https://download.java.net/java/early_access/jdk22/15/GPL/openjdk-22-ea+15_linux-x64_bin.tar.gz -O jdk.tar.gz +wget https://download.java.net/java/early_access/jdk22/31/GPL/openjdk-22-ea+31_linux-x64_bin.tar.gz -O jdk.tar.gz tar -xzf jdk.tar.gz -C /opt/ -mv /opt/jdk-22 /opt/jdk \ No newline at end of file +mv /opt/jdk-22 /opt/jdk From 64e6d50118379b940d0e8cbe145d5a083957ed7a Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:39:10 +0100 Subject: [PATCH 27/65] [build] Ensure build knows where lombok.patcher v0.50 lives --- ...her-0.46.xml => org.projectlombok-lombok.patcher-0.50.xml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename buildScripts/ivy-repo/{org.projectlombok-lombok.patcher-0.46.xml => org.projectlombok-lombok.patcher-0.50.xml} (87%) diff --git a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml similarity index 87% rename from buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml rename to buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml index 37de93e6..e6af2118 100644 --- a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml +++ b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,6 @@ - + From ddf8778db523dbc844fe9605d5a7b2e91270e808 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:45:03 +0100 Subject: [PATCH 28/65] Oof, git tracks executable flag. It wasn't set which broke java-22.sh --- docker/provision/jdk/java-22.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 docker/provision/jdk/java-22.sh diff --git a/docker/provision/jdk/java-22.sh b/docker/provision/jdk/java-22.sh old mode 100644 new mode 100755 From b669c7d6a983403c03bc218a3a0832fe29b4d74e Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 12 Jan 2024 01:52:58 +0100 Subject: [PATCH 29/65] [build] Add gradle 8.5 to integration test docker setup --- docker/gradle/Dockerfile | 2 +- docker/gradle/readme.md | 5 +++-- docker/provision/gradle/gradle-8.5.sh | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100755 docker/provision/gradle/gradle-8.5.sh diff --git a/docker/gradle/Dockerfile b/docker/gradle/Dockerfile index cfb32939..b83f7f0e 100644 --- a/docker/gradle/Dockerfile +++ b/docker/gradle/Dockerfile @@ -7,7 +7,7 @@ RUN provision/jdk/java-${jdk}.sh ARG lombokjar=lombok.jar ADD https://projectlombok.org/downloads/${lombokjar} /lombok.jar -ARG gradle=8.3 +ARG gradle=8.5 ADD provision/gradle/gradle-${gradle}.sh provision/gradle/gradle-${gradle}.sh RUN provision/gradle/gradle-${gradle}.sh diff --git a/docker/gradle/readme.md b/docker/gradle/readme.md index 5b827801..2579f032 100644 --- a/docker/gradle/readme.md +++ b/docker/gradle/readme.md @@ -2,11 +2,12 @@ [_(general configuration and options)_](../readme.md) -### `ARG gradle=8.3` +### `ARG gradle=8.5` The gradle version to be used. Supported values: -- `8.3` (default) +- `8.5` (default) +- `8.3` - `7.6.1` - `6.8.3` diff --git a/docker/provision/gradle/gradle-8.5.sh b/docker/provision/gradle/gradle-8.5.sh new file mode 100755 index 00000000..2f13a210 --- /dev/null +++ b/docker/provision/gradle/gradle-8.5.sh @@ -0,0 +1,4 @@ +apt-get update && apt-get install -y wget unzip +wget https://github.com/gradle/gradle-distributions/releases/download/v8.5.0/gradle-8.5-bin.zip -O gradle.zip +mkdir /opt/gradle && unzip -d /opt/gradle gradle.zip +mv /opt/gradle/gradle-8.5 /opt/gradle/gradle From 1342aa83db05e133e304e5d32ea81837b9fb3fb7 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 15 Jan 2024 16:49:59 +0100 Subject: [PATCH 30/65] Exclude Gradle on 22 Thanks @msamoylych for the solution --- .github/workflows/ant.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 892b3fc6..fc88c95e 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -162,6 +162,8 @@ jobs: - {name: "gradle", cmd: "gradle assemble"} - {name: "ant", cmd: "ant dist"} - {name: "bazel", cmd: "bazel build //:ProjectRunner"} + exclude: + - {tool: {name: "gradle", cmd: "gradle assemble"}, jdk: 22} fail-fast: false env: IMAGE_NAME: lombok-${{ matrix.tool.name }}-jdk${{ matrix.jdk }} From fd55c7aa93f3afc08c8694d3f9e59032cf42aedf Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 14 Jan 2024 14:21:48 +0100 Subject: [PATCH 31/65] [ci] Use variables and add eclipse I build tests --- .github/workflows/ant.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index fc88c95e..2eb66be8 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -40,6 +40,8 @@ jobs: test-javac: runs-on: ubuntu-latest needs: build + env: + EA_JDK: 22 strategy: matrix: jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22] @@ -56,14 +58,14 @@ jobs: uses: actions/checkout@v3 - name: Set up JDK ${{ matrix.jdk }} - if: ${{ matrix.jdk < 21 }} + if: ${{ matrix.jdk < env.EA_JDK }} uses: actions/setup-java@v3 with: java-version: ${{ matrix.jdk }} distribution: 'zulu' - - name: Set up JDK 21 and up including Early Access releases - if: ${{ matrix.jdk >= 21 }} + - name: Set up JDK ${{ matrix.jdk }} Early Access release + if: ${{ matrix.jdk >= env.EA_JDK }} uses: oracle-actions/setup-java@v1 with: website: jdk.java.net @@ -71,11 +73,13 @@ jobs: version: latest - name: Install Ant + env: + ANT_VERSION: 1.10.14 run: | - wget https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.13-bin.zip - unzip apache-ant-1.10.13-bin.zip -d "${HOME}" - echo "ANT_HOME=${HOME}/apache-ant-1.10.13" >> $GITHUB_ENV - echo "${HOME}/apache-ant-1.10.13/bin" >> $GITHUB_PATH + wget https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.zip + unzip apache-ant-$ANT_VERSION-bin.zip -d "${HOME}" + echo "ANT_HOME=${HOME}/apache-ant-$ANT_VERSION" >> $GITHUB_ENV + echo "${HOME}/apache-ant-$ANT_VERSION/bin" >> $GITHUB_PATH - name: Cache dependencies uses: actions/cache@v3 @@ -102,10 +106,12 @@ jobs: - eclipse-202212 - eclipse-202309 - eclipse-202312 + - eclipse-I-build - eclipse-oxygen-full - eclipse-2022-03-full - eclipse-2023-09-full - eclipse-2023-12-full + - eclipse-I-build-full - ecj11 - ecj14 - ecj16 From f277791cf0ecaf7297bb7a7313b2dac38b40597e Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Mon, 6 Nov 2023 17:34:21 +0100 Subject: [PATCH 32/65] [fixes #3529] Set real field initializer source Eclipse copies the field initializer source code if it is a constant. For generated nodes we have to read it from the ast node and not from the source file. --- .../lombok/eclipse/agent/EclipsePatcher.java | 39 ++++++++++- .../lombok/launch/PatchFixesHider.java | 68 ++++++++++++++++++- .../Annotation.java | 5 ++ .../Constants.java | 8 +++ .../fieldNameConstantsInAnnotation/Usage.java | 5 ++ .../src/lombok/eclipse/EclipseTests.java | 3 +- .../lombok/eclipse/compile/NoErrorsTest.java | 68 +++++++++++++++++++ 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java create mode 100644 test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java create mode 100644 test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java create mode 100644 test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index c5b0ea07..c176f515 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2023 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -100,6 +100,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchJavadoc(sm); patchASTConverterLiterals(sm); patchASTNodeSearchUtil(sm); + patchFieldInitializer(sm); patchPostCompileHookEcj(sm); @@ -1029,6 +1030,42 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .build()); } + private static void patchFieldInitializer(ScriptManager sm) { + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField() + .targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor") + .fieldName("$fieldInfo") + .fieldType("Ljava/lang/Object;") + .build()); + + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField() + .targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor") + .fieldName("$sourceFieldElementInfo") + .fieldType("Lorg/eclipse/jdt/internal/core/SourceFieldElementInfo;") + .build()); + + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int")) + .decisionMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeFieldInfo", "boolean", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")) + .request(StackRequest.THIS) + .transplant() + .build()); + + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int")) + .methodToWrap(new Hook("org.eclipse.jdt.internal.core.SourceFieldElementInfo", "", "void")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeSourceFieldElementInfo", "void", "org.eclipse.jdt.internal.core.SourceFieldElementInfo", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")) + .requestExtra(StackRequest.THIS) + .transplant() + .build()); + + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue() + .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "overwriteInitializer", "void", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")) + .request(StackRequest.THIS) + .transplant() + .build()); + } + private static void patchCrossModuleClassLoading(ScriptManager sm) { sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue() .target(new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "")) diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index c88f3171..3bdf7974 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2023 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 @@ -52,7 +52,9 @@ import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.search.SearchMatch; +import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.FieldInfo; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; @@ -61,7 +63,9 @@ 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.CompilationUnitStructureRequestor; import org.eclipse.jdt.internal.core.SourceField; +import org.eclipse.jdt.internal.core.SourceFieldElementInfo; 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; @@ -935,6 +939,68 @@ final class PatchFixesHider { } } + public static class FieldInitializer { + public static final Field INFO_STACK; + public static final Field FIELD_INFO; + public static final Field SOURCE_FIELD_ELEMENT_INFO; + public static final Field INITIALIZATION_SOURCE; + public static final Field NODE; + public static final boolean INITIALIZED; + + static { + INFO_STACK = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "infoStack"); + FIELD_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$fieldInfo"); + SOURCE_FIELD_ELEMENT_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$sourceFieldElementInfo"); + INITIALIZATION_SOURCE = Permit.permissiveGetField(SourceFieldElementInfo.class, "initializationSource"); + NODE = Permit.permissiveGetField(FieldInfo.class, "node"); + INITIALIZED = INFO_STACK != null && FIELD_INFO != null && SOURCE_FIELD_ELEMENT_INFO != null && INITIALIZATION_SOURCE != null && NODE != null; + } + + public static boolean storeFieldInfo(CompilationUnitStructureRequestor compilationUnitStructureRequestor) { + try { + if (INITIALIZED) { + Stack infoStack = Permit.get(INFO_STACK, compilationUnitStructureRequestor); + Object fieldInfo = infoStack.peek(); + Permit.set(FIELD_INFO, compilationUnitStructureRequestor, fieldInfo); + } + } catch (Exception e) { + // do not break eclipse + } + return false; + } + public static void storeSourceFieldElementInfo(SourceFieldElementInfo fieldInfo, CompilationUnitStructureRequestor compilationUnitStructureRequestor) { + try { + if (INITIALIZED) { + Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, fieldInfo); + } + } catch (Exception e) { + // do not break eclipse + } + } + + public static void overwriteInitializer(CompilationUnitStructureRequestor compilationUnitStructureRequestor) { + try { + if (INITIALIZED) { + FieldInfo fieldInfo = Permit.get(FIELD_INFO, compilationUnitStructureRequestor); + Permit.set(FIELD_INFO, compilationUnitStructureRequestor, null); + + SourceFieldElementInfo sourceFieldElementInfo = Permit.get(SOURCE_FIELD_ELEMENT_INFO,compilationUnitStructureRequestor); + Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, null); + + if (sourceFieldElementInfo.getInitializationSource() != null) { + AbstractVariableDeclaration node = Permit.get(NODE, fieldInfo); + + if (PatchFixes.isGenerated(node)) { + Permit.set(INITIALIZATION_SOURCE, sourceFieldElementInfo, node.initialization.toString().toCharArray()); + } + } + } + } catch (Exception e) { + // do not break eclipse + } + } + } + public static class Tests { public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) { return (StringBuffer) printMethod(methodDeclaration, tab, (Object) output, type); diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java new file mode 100644 index 00000000..e3ecb40f --- /dev/null +++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java @@ -0,0 +1,5 @@ +package pkg; + +public @interface Annotation { + String value(); +} \ No newline at end of file diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java new file mode 100644 index 00000000..fad3811f --- /dev/null +++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java @@ -0,0 +1,8 @@ +package pkg; + +import lombok.experimental.FieldNameConstants; + +@FieldNameConstants +public class Constants { + String test; +} \ No newline at end of file diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java new file mode 100644 index 00000000..5f8880ef --- /dev/null +++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java @@ -0,0 +1,5 @@ +package pkg; + +@Annotation(Constants.Fields.test) +public class Usage { +} \ 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 5fba9903..2e219995 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseTests.java +++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java @@ -5,6 +5,7 @@ import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import lombok.eclipse.cleanup.CleanupTest; +import lombok.eclipse.compile.NoErrorsTest; import lombok.eclipse.edit.SelectTest; import lombok.eclipse.refactoring.ExtractInterfaceTest; import lombok.eclipse.refactoring.InlineTest; @@ -12,7 +13,7 @@ import lombok.eclipse.refactoring.RenameTest; import lombok.eclipse.references.FindReferencesTest; @RunWith(Suite.class) -@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class}) +@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class}) public class EclipseTests { } diff --git a/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java new file mode 100644 index 00000000..9fd02d9f --- /dev/null +++ b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java @@ -0,0 +1,68 @@ +package lombok.eclipse.compile; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IProblemRequestor; +import org.eclipse.jdt.core.WorkingCopyOwner; +import org.eclipse.jdt.core.compiler.IProblem; +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 NoErrorsTest { + + @Rule + public SetupSingleFileTest setup = new SetupSingleFileTest(); + + @Test + public void fieldNameConstantsInAnnotation() throws Exception { + ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("Usage.java"); + + final List problems = new ArrayList(); + final IProblemRequestor requestor = new IProblemRequestor() { + @Override + public void acceptProblem(IProblem problem) { + problems.add(problem); + } + + @Override + public void beginReporting() { + problems.clear(); + } + + @Override + public void endReporting() { + } + + @Override + public boolean isActive() { + return true; + } + }; + + WorkingCopyOwner workingCopyOwner = new WorkingCopyOwner() { + @Override + public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) { + return requestor; + } + }; + + ICompilationUnit workingCopy = cu.getWorkingCopy(workingCopyOwner, null); + try { + workingCopy.reconcile(ICompilationUnit.NO_AST, true, true, workingCopy.getOwner(), null); + } finally { + workingCopy.discardWorkingCopy(); + } + + System.out.println(problems); + assertTrue(problems.isEmpty()); + } +} From 2db9ca7ea4bbd140a65fc9a6b1df547638ed46c8 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Mon, 15 Jan 2024 22:59:52 +0100 Subject: [PATCH 33/65] Add license headers --- .../src/lombok/eclipse/EclipseRunner.java | 21 +++++++++++++++++++ .../src/lombok/eclipse/EclipseTests.java | 21 +++++++++++++++++++ .../src/lombok/eclipse/RefactoringUtils.java | 21 +++++++++++++++++++ .../lombok/eclipse/SetupBeforeAfterTest.java | 21 +++++++++++++++++++ .../lombok/eclipse/SetupSingleFileTest.java | 21 +++++++++++++++++++ .../eclipse/src/lombok/eclipse/SetupTest.java | 21 +++++++++++++++++++ .../lombok/eclipse/cleanup/CleanupTest.java | 21 +++++++++++++++++++ .../lombok/eclipse/compile/NoErrorsTest.java | 21 +++++++++++++++++++ .../src/lombok/eclipse/edit/SelectTest.java | 21 +++++++++++++++++++ .../refactoring/ExtractInterfaceTest.java | 21 +++++++++++++++++++ .../eclipse/refactoring/InlineTest.java | 21 +++++++++++++++++++ .../eclipse/refactoring/RenameTest.java | 21 +++++++++++++++++++ .../references/FindReferencesTest.java | 21 +++++++++++++++++++ 13 files changed, 273 insertions(+) diff --git a/test/eclipse/src/lombok/eclipse/EclipseRunner.java b/test/eclipse/src/lombok/eclipse/EclipseRunner.java index 1e1c17fe..36e98d9e 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseRunner.java +++ b/test/eclipse/src/lombok/eclipse/EclipseRunner.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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; import java.io.File; diff --git a/test/eclipse/src/lombok/eclipse/EclipseTests.java b/test/eclipse/src/lombok/eclipse/EclipseTests.java index 2e219995..04f78f0f 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseTests.java +++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022-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; import org.junit.runner.RunWith; diff --git a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java index 38349d2d..2362ff11 100644 --- a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java +++ b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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; import static org.junit.Assert.assertTrue; diff --git a/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java b/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java index 05deabde..ff51ef13 100644 --- a/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java +++ b/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022-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 + * 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; import static org.junit.Assert.assertEquals; diff --git a/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java b/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java index 47010f0c..d4b934ce 100644 --- a/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java +++ b/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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; import java.io.File; diff --git a/test/eclipse/src/lombok/eclipse/SetupTest.java b/test/eclipse/src/lombok/eclipse/SetupTest.java index fe8d469c..d3a2f1b0 100644 --- a/test/eclipse/src/lombok/eclipse/SetupTest.java +++ b/test/eclipse/src/lombok/eclipse/SetupTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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; import java.io.File; diff --git a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java index 2d018228..76956aff 100644 --- a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java +++ b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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.cleanup; import static lombok.eclipse.RefactoringUtils.performRefactoring; diff --git a/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java index 9fd02d9f..6d81d381 100644 --- a/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java +++ b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java @@ -1,3 +1,24 @@ +/* + * 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.compile; import static org.junit.Assert.assertTrue; diff --git a/test/eclipse/src/lombok/eclipse/edit/SelectTest.java b/test/eclipse/src/lombok/eclipse/edit/SelectTest.java index 9f348a0c..a9723618 100644 --- a/test/eclipse/src/lombok/eclipse/edit/SelectTest.java +++ b/test/eclipse/src/lombok/eclipse/edit/SelectTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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.edit; import static org.junit.Assert.assertEquals; diff --git a/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java b/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java index d4c892f3..1ad64398 100644 --- a/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java +++ b/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022 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.refactoring; import static lombok.eclipse.RefactoringUtils.performRefactoring; diff --git a/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java b/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java index 1a3315b7..25a21d62 100644 --- a/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java +++ b/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * 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.refactoring; import static lombok.eclipse.RefactoringUtils.performRefactoring; diff --git a/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java b/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java index 8ce4874c..7f085f08 100644 --- a/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java +++ b/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022-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 + * 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.refactoring; import static lombok.eclipse.RefactoringUtils.performRefactoring; diff --git a/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java b/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java index a4668088..e2806ea3 100644 --- a/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java +++ b/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 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 + * 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.references; import static org.junit.Assert.*; From 2773ed5943f3ca3055c915dda325b0503944e9b0 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 17 Jan 2024 02:14:45 +0100 Subject: [PATCH 34/65] [changelog] [#3529] Record this bug fixed in previous commit in the changelog --- doc/changelog.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 4379eb96..a3b3a48a 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -6,8 +6,8 @@ Lombok Changelog * FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506). * NECROMANCY: Inlining a generated getter in eclipse would result in eclipse incorrectly replacing calls with `@Getter` instead of the actual field's name. [Issue #562](https://github.com/projectlombok/lombok/issues/562). This issue is almost old enough to drink. Points for dedication go to Rawi for fixing this one. * BUGFIX: Many lombok features wouldn't work properly on records contained within an outer type unless you explicitly marked it `static`. [Issue #3497](https://github.com/projectlombok/lombok/issues/3497) [Issue #3559](https://github.com/projectlombok/lombok/issues/3559). -* BUGFIX: Eclipse projects using the com.pro-crafting.tools:jasperreports-plugin will now compile -* We recently released v1.18.30; there is no edge release since then. +* BUGFIX: Eclipse projects using the `com.pro-crafting.tools:jasperreports-plugin` will now compile. +* BUGFIX: `@FieldNameConstants` now works when generated fields are involved. [Issue #3529](https://github.com/projectlombok/lombok/issues/3529). ### v1.18.30 (September 20th, 2023) * PLATFORM: Initial JDK21 support added. [Issue #3393](https://github.com/projectlombok/lombok/issues/3393). From 11322138e508b0e05dcd00fa463e56ba242c4da1 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Tue, 23 Jan 2024 12:16:26 +0100 Subject: [PATCH 35/65] SuperBuilder: handle annotated types in extends clause for javac --- .../javac/handlers/HandleSuperBuilder.java | 2 + .../SuperBuilderWithAnnotatedTypeParam.java | 117 ++++++++++++++++++ .../SuperBuilderWithAnnotatedTypeParam.java | 94 ++++++++++++++ .../SuperBuilderWithAnnotatedTypeParam.java | 28 +++++ 4 files changed, 241 insertions(+) create mode 100644 test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java create mode 100644 test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java create mode 100644 test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 3a230437..d64daf38 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -1108,6 +1108,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { typeParamsForBuilderParameter.append(copySelect(maker, (JCFieldAccess) typeParam)); } else if (typeParam instanceof JCTypeApply) { typeParamsForBuilderParameter.append(cloneType(maker, (JCTypeApply)typeParam, source)); + } else if (JCAnnotatedTypeReflect.is(typeParam)) { + typeParamsForBuilderParameter.append(cloneType(maker, (JCExpression)typeParam, source)); } } return typeParamsForBuilderParameter; diff --git a/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java new file mode 100644 index 00000000..2fd3e86a --- /dev/null +++ b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java @@ -0,0 +1,117 @@ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +public class SuperBuilderWithAnnotatedTypeParam { + @Documented + @Target({ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE}) + @Retention(RetentionPolicy.RUNTIME) + public @interface MyAnnotation { + } + public static class Parent { + A field1; + @java.lang.SuppressWarnings("all") + public static abstract class ParentBuilder, B extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder> { + @java.lang.SuppressWarnings("all") + private A field1; + /** + * @return {@code this}. + */ + @java.lang.SuppressWarnings("all") + public B field1(final A field1) { + this.field1 = field1; + return self(); + } + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder(field1=" + this.field1 + ")"; + } + } + @java.lang.SuppressWarnings("all") + private static final class ParentBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder, SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl> { + @java.lang.SuppressWarnings("all") + private ParentBuilderImpl() { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl self() { + return this; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public SuperBuilderWithAnnotatedTypeParam.Parent build() { + return new SuperBuilderWithAnnotatedTypeParam.Parent(this); + } + } + @java.lang.SuppressWarnings("all") + protected Parent(final SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder b) { + this.field1 = b.field1; + } + @java.lang.SuppressWarnings("all") + public static SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder builder() { + return new SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl(); + } + } + public static class Child extends Parent<@MyAnnotation String> { + double field3; + @java.lang.SuppressWarnings("all") + public static abstract class ChildBuilder> extends Parent.ParentBuilder<@MyAnnotation String, C, B> { + @java.lang.SuppressWarnings("all") + private double field3; + /** + * @return {@code this}. + */ + @java.lang.SuppressWarnings("all") + public B field3(final double field3) { + this.field3 = field3; + return self(); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder(super=" + super.toString() + ", field3=" + this.field3 + ")"; + } + } + @java.lang.SuppressWarnings("all") + private static final class ChildBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder { + @java.lang.SuppressWarnings("all") + private ChildBuilderImpl() { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl self() { + return this; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public SuperBuilderWithAnnotatedTypeParam.Child build() { + return new SuperBuilderWithAnnotatedTypeParam.Child(this); + } + } + @java.lang.SuppressWarnings("all") + protected Child(final SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder b) { + super(b); + this.field3 = b.field3; + } + @java.lang.SuppressWarnings("all") + public static SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder builder() { + return new SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl(); + } + } + public static void test() { + Child x = Child.builder().field3(0.0).field1("string").build(); + } +} diff --git a/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java new file mode 100644 index 00000000..c3756583 --- /dev/null +++ b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java @@ -0,0 +1,94 @@ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +public class SuperBuilderWithAnnotatedTypeParam { + public @Documented @Target({ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { + } + public static @lombok.experimental.SuperBuilder class Parent { + public static abstract @java.lang.SuppressWarnings("all") class ParentBuilder, B extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder> { + private @java.lang.SuppressWarnings("all") A field1; + public ParentBuilder() { + super(); + } + /** + * @return {@code this}. + */ + public @java.lang.SuppressWarnings("all") B field1(final A field1) { + this.field1 = field1; + return self(); + } + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder(field1=" + this.field1) + ")"); + } + } + private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder, SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl> { + private ParentBuilderImpl() { + super(); + } + protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl self() { + return this; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent build() { + return new SuperBuilderWithAnnotatedTypeParam.Parent(this); + } + } + A field1; + protected @java.lang.SuppressWarnings("all") Parent(final SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder b) { + super(); + this.field1 = b.field1; + } + public static @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder builder() { + return new SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl(); + } + } + public static @lombok.experimental.SuperBuilder class Child extends Parent<@MyAnnotation String> { + public static abstract @java.lang.SuppressWarnings("all") class ChildBuilder> extends Parent.ParentBuilder<@MyAnnotation String, C, B> { + private @java.lang.SuppressWarnings("all") double field3; + public ChildBuilder() { + super(); + } + /** + * @return {@code this}. + */ + public @java.lang.SuppressWarnings("all") B field3(final double field3) { + this.field3 = field3; + return self(); + } + protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build(); + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((("SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder(super=" + super.toString()) + ", field3=") + this.field3) + ")"); + } + } + private static final @java.lang.SuppressWarnings("all") class ChildBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder { + private ChildBuilderImpl() { + super(); + } + protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl self() { + return this; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child build() { + return new SuperBuilderWithAnnotatedTypeParam.Child(this); + } + } + double field3; + protected @java.lang.SuppressWarnings("all") Child(final SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder b) { + super(b); + this.field3 = b.field3; + } + public static @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder builder() { + return new SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl(); + } + } + public SuperBuilderWithAnnotatedTypeParam() { + super(); + } + public static void test() { + Child x = Child.builder().field3(0.0).field1("string").build(); + } +} diff --git a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java new file mode 100644 index 00000000..a1e692bb --- /dev/null +++ b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java @@ -0,0 +1,28 @@ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; + +public class SuperBuilderWithAnnotatedTypeParam { + @Documented + @Target( { ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE }) + @Retention(RetentionPolicy.RUNTIME) + public @interface MyAnnotation { + } + + @lombok.experimental.SuperBuilder + public static class Parent { + A field1; + } + + @lombok.experimental.SuperBuilder + public static class Child extends Parent<@MyAnnotation String> { + double field3; + } + + public static void test() { + Child x = Child.builder().field3(0.0).field1("string").build(); + } +} From 2aaae4e9be616c444c84527a30ad536373bbcbaf Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Tue, 23 Jan 2024 13:19:20 +0100 Subject: [PATCH 36/65] only run test for java >= 8 --- .../resource/before/SuperBuilderWithAnnotatedTypeParam.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java index a1e692bb..3f008040 100644 --- a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java +++ b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java @@ -1,3 +1,4 @@ +//VERSION 8: import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; From 603d512f93dab073b164661a408ecc6ec5313a68 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Tue, 23 Jan 2024 13:57:38 +0100 Subject: [PATCH 37/65] only run test for java >= 8 --- .../after-delombok/SuperBuilderWithAnnotatedTypeParam.java | 1 + .../resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java | 1 + .../resource/before/SuperBuilderWithAnnotatedTypeParam.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java index 2fd3e86a..f7ffe2fd 100644 --- a/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java +++ b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java @@ -1,3 +1,4 @@ +//version 8: import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java index c3756583..9dea5ba0 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java @@ -1,3 +1,4 @@ +//version 8: import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java index 3f008040..4f5bed50 100644 --- a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java +++ b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java @@ -1,4 +1,4 @@ -//VERSION 8: +//version 8: import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; From cad428ea74d9c922f40e1933d6d5a48efeee10d1 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 28 Jan 2024 15:50:22 +0100 Subject: [PATCH 38/65] Use version numbers in eclipse dependency downloader --- buildScripts/setup.ant.xml | 4 +- .../DownloadEclipseDependencies.java | 21 +++++ .../eclipse/dependencies/UniqueQueue.java | 21 ----- .../eclipse/dependencies/UpdateSite.java | 79 ++++++++++-------- .../eclipse/dependencies/model/Child.java | 21 +++++ .../eclipse/dependencies/model/Provided.java | 30 ++++++- .../dependencies/model/Repository.java | 21 +++++ .../eclipse/dependencies/model/Required.java | 30 ++++++- .../eclipse/dependencies/model/Unit.java | 31 ++++++- .../eclipse/dependencies/model/Version.java | 66 +++++++++++++++ .../dependencies/model/VersionAdapter.java | 38 +++++++++ .../dependencies/model/VersionRange.java | 80 +++++++++++++++++++ .../model/VersionRangeAdapter.java | 38 +++++++++ 13 files changed, 418 insertions(+), 62 deletions(-) delete mode 100644 src/support/lombok/eclipse/dependencies/UniqueQueue.java create mode 100644 src/support/lombok/eclipse/dependencies/model/Version.java create mode 100644 src/support/lombok/eclipse/dependencies/model/VersionAdapter.java create mode 100644 src/support/lombok/eclipse/dependencies/model/VersionRange.java create mode 100644 src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index f8fb5e51..ba15d491 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -201,11 +201,9 @@ This buildfile is part of projectlombok.org. It sets up the build itself. - - + - diff --git a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java index 2391a1a9..0e8d5895 100644 --- a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java +++ b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2022-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.dependencies; import java.io.BufferedInputStream; diff --git a/src/support/lombok/eclipse/dependencies/UniqueQueue.java b/src/support/lombok/eclipse/dependencies/UniqueQueue.java deleted file mode 100644 index 6a97612e..00000000 --- a/src/support/lombok/eclipse/dependencies/UniqueQueue.java +++ /dev/null @@ -1,21 +0,0 @@ -package lombok.eclipse.dependencies; - -import java.util.ArrayDeque; -import java.util.HashSet; -import java.util.Set; - -/** - * An incomplete implementation of a queue that maintains a history of all queued items and ensures unique elements. - * Elements cannot be added to the queue if they already exist in the history. - */ -public class UniqueQueue extends ArrayDeque { - private Set added = new HashSet<>(); - - @Override - public boolean add(T e) { - if (added.add(e)) { - return super.add(e); - } - return false; - } -} diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java index c3379361..40524568 100644 --- a/src/support/lombok/eclipse/dependencies/UpdateSite.java +++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java @@ -1,3 +1,24 @@ +/* + * 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.dependencies; import java.io.BufferedInputStream; @@ -5,11 +26,9 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.ArrayDeque; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.stream.Collectors; @@ -25,10 +44,10 @@ import javax.xml.transform.sax.SAXSource; import org.xml.sax.InputSource; import lombok.eclipse.dependencies.model.Child; -import lombok.eclipse.dependencies.model.Provided; import lombok.eclipse.dependencies.model.Repository; import lombok.eclipse.dependencies.model.Required; import lombok.eclipse.dependencies.model.Unit; +import lombok.eclipse.dependencies.model.VersionRange; public class UpdateSite { private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); @@ -38,13 +57,11 @@ public class UpdateSite { private JAXBContext jaxbContext; private Repository repository; - private Map> providesIndex; private String resolvedUrl; private SAXParserFactory saxParserFactory; public UpdateSite() throws Exception { jaxbContext = JAXBContext.newInstance(Repository.class); - providesIndex = new HashMap<>(); SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); @@ -72,15 +89,7 @@ public class UpdateSite { try (InputStream inputStream = readJarOrXml(resolvedUrl, "content")) { repository = unmarshalRepository(inputStream); - - // Build index - for (Unit unit : repository.units) { - for (Provided provides : unit.provides) { - providesIndex.computeIfAbsent(provides.namespace + ":" + provides.name, k -> new ArrayList<>()).add(unit); - } - } } - ; } public Set resolveWithoutDependencies(List dependencies) { @@ -92,40 +101,42 @@ public class UpdateSite { } private Set resolve(List dependencies, boolean withDependencies) { - Queue toResolve = new UniqueQueue<>(); + Queue toResolve = new ArrayDeque<>(); for (String dependency : dependencies) { - toResolve.add(dependency); + String[] split = dependency.split(":"); + Required required = new Required(); + required.namespace = split[0]; + required.name = split[1]; + required.range = VersionRange.ALL; + toResolve.add(required); } Set resolved = new HashSet<>(); while (!toResolve.isEmpty()) { - String next = toResolve.poll(); + Required next = toResolve.poll(); - List providedUnits = providesIndex.get(next); + // Skip already resolved + if (resolved.stream().anyMatch(u -> u.satisfies(next))) { + continue; + } + + List satisfyingUnits = repository.units.stream().filter(u -> u.satisfies(next)).collect(Collectors.toList()); // Skip unknown - if (providedUnits == null) { + if (satisfyingUnits.isEmpty()) { System.out.println("Skipping unknown unit " + next); continue; } - // Remove a.jre.javase dependency - List filteredProvidedUnits = providedUnits.stream() - .filter(u -> !u.id.equals("a.jre.javase")) // Remove - .collect(Collectors.toList()); - if (filteredProvidedUnits.size() == 0) { - // This is a JDK only dependency, skip + // Skip JDK dependencies + boolean jdkDependency = satisfyingUnits.stream().anyMatch(u -> u.id.equals("a.jre.javase")); + if (jdkDependency) { continue; } - // Skip ambiguous (we could use version ranges to solve that...) - if (filteredProvidedUnits.size() > 1) { - boolean alreadyResolved = filteredProvidedUnits.stream().anyMatch(resolved::contains); - if (!alreadyResolved) { - System.out.println("Ambiguous resolution for " + next + ": " + filteredProvidedUnits.toString()); - continue; - } + if (satisfyingUnits.size() > 1) { + System.out.println("Ambiguous resolution for " + next + ": " + satisfyingUnits.toString() + ", picking first"); } - Unit unit = filteredProvidedUnits.get(0); + Unit unit = satisfyingUnits.get(0); resolved.add(unit); if (withDependencies && unit.requires != null) { @@ -133,7 +144,7 @@ public class UpdateSite { if (required.optional) continue; if (!matchesFilter(required.filter)) continue; - toResolve.add(required.namespace + ":" + required.name); + toResolve.add(required); } } } diff --git a/src/support/lombok/eclipse/dependencies/model/Child.java b/src/support/lombok/eclipse/dependencies/model/Child.java index 818645e2..1aedc77f 100644 --- a/src/support/lombok/eclipse/dependencies/model/Child.java +++ b/src/support/lombok/eclipse/dependencies/model/Child.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2023-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.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; diff --git a/src/support/lombok/eclipse/dependencies/model/Provided.java b/src/support/lombok/eclipse/dependencies/model/Provided.java index b531d3e1..29762f8c 100644 --- a/src/support/lombok/eclipse/dependencies/model/Provided.java +++ b/src/support/lombok/eclipse/dependencies/model/Provided.java @@ -1,6 +1,28 @@ +/* + * Copyright (C) 2023-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.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; public class Provided { @XmlAttribute @@ -8,5 +30,11 @@ public class Provided { @XmlAttribute public String name; @XmlAttribute - public String version; + @XmlJavaTypeAdapter(VersionAdapter.class) + public Version version; + + @Override + public String toString() { + return namespace + ":" + name + "_" + version; + } } diff --git a/src/support/lombok/eclipse/dependencies/model/Repository.java b/src/support/lombok/eclipse/dependencies/model/Repository.java index 1d81bf8c..17c1b236 100644 --- a/src/support/lombok/eclipse/dependencies/model/Repository.java +++ b/src/support/lombok/eclipse/dependencies/model/Repository.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2023-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.dependencies.model; import java.util.List; diff --git a/src/support/lombok/eclipse/dependencies/model/Required.java b/src/support/lombok/eclipse/dependencies/model/Required.java index 36fbe46e..0d5ae2d0 100644 --- a/src/support/lombok/eclipse/dependencies/model/Required.java +++ b/src/support/lombok/eclipse/dependencies/model/Required.java @@ -1,7 +1,29 @@ +/* + * Copyright (C) 2023-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.dependencies.model; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; public class Required { @XmlAttribute @@ -9,9 +31,15 @@ public class Required { @XmlAttribute public String name; @XmlAttribute - public String range; + @XmlJavaTypeAdapter(VersionRangeAdapter.class) + public VersionRange range; @XmlAttribute public boolean optional; @XmlElement public String filter; + + @Override + public String toString() { + return namespace + ":" + name + "_" + range; + } } diff --git a/src/support/lombok/eclipse/dependencies/model/Unit.java b/src/support/lombok/eclipse/dependencies/model/Unit.java index 82d7809e..781651ec 100644 --- a/src/support/lombok/eclipse/dependencies/model/Unit.java +++ b/src/support/lombok/eclipse/dependencies/model/Unit.java @@ -1,3 +1,24 @@ +/* + * Copyright (C) 2023-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.dependencies.model; import java.util.List; @@ -5,12 +26,14 @@ import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; public class Unit { @XmlAttribute public String id; @XmlAttribute - public String version; + @XmlJavaTypeAdapter(VersionAdapter.class) + public Version version; @XmlElementWrapper(name = "provides") @XmlElement(name="provided") @@ -19,7 +42,11 @@ public class Unit { @XmlElementWrapper(name = "requires") @XmlElement(name="required") public List requires; - + + public boolean satisfies(Required required) { + return provides.stream().anyMatch(p -> p.namespace.equals(required.namespace) && p.name.equals(required.name) && required.range.contains(p.version)); + } + @Override public String toString() { return id + "_" + version; diff --git a/src/support/lombok/eclipse/dependencies/model/Version.java b/src/support/lombok/eclipse/dependencies/model/Version.java new file mode 100644 index 00000000..0ebcf2ef --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/model/Version.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.dependencies.model; + +public class Version { + private int major; + private int minor; + private int micro; + private String qualifier = ""; + + public static Version parse(String v) { + String[] parts = v.split("\\.", 4); + + Version version = new Version(); + version.major = Integer.parseInt(parts[0]); + if (parts.length > 1) { + version.minor = Integer.parseInt(parts[1]); + } + if (parts.length > 2) { + version.micro = Integer.parseInt(parts[2]); + } + if (parts.length > 3) { + version.qualifier = parts[3]; + } + return version; + } + + public int compareTo(Version other) { + int result = major - other.major; + if (result != 0) return result; + + result = minor - other.minor; + if (result != 0) return result; + + result = micro - other.micro; + if (result != 0) return result; + + return qualifier.compareTo(other.qualifier); + } + + @Override + public String toString() { + String result = major + "." + minor + "." + micro; + if (!qualifier.isEmpty()) result += "." + qualifier; + return result; + } +} diff --git a/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java b/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java new file mode 100644 index 00000000..3c0f0ca1 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java @@ -0,0 +1,38 @@ +/* + * 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.dependencies.model; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +public class VersionAdapter extends XmlAdapter { + + @Override + public Version unmarshal(String v) throws Exception { + return Version.parse(v); + } + + @Override + public String marshal(Version v) throws Exception { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/support/lombok/eclipse/dependencies/model/VersionRange.java b/src/support/lombok/eclipse/dependencies/model/VersionRange.java new file mode 100644 index 00000000..7dda2dce --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/model/VersionRange.java @@ -0,0 +1,80 @@ +/* + * 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.dependencies.model; + +public class VersionRange { + public static final VersionRange ALL = VersionRange.parse("0.0.0"); + + private Version min; + private Version max; + private boolean leftInclusive; + private boolean leftExclusive; + private boolean rightInclusive; + private boolean rightExclusive; + + public static VersionRange parse(String v) { + VersionRange versionRange = new VersionRange(); + versionRange.leftInclusive = v.startsWith("["); + versionRange.leftExclusive = v.startsWith("("); + versionRange.rightInclusive = v.endsWith("]"); + versionRange.rightExclusive = v.endsWith(")"); + + if (!versionRange.leftInclusive && !versionRange.leftExclusive) { + Version version = Version.parse(v); + versionRange.min = version; + versionRange.leftInclusive = true; + return versionRange; + } + + String[] parts = v.replaceAll("[\\[\\(\\)\\]]", "").split(","); + versionRange.min = Version.parse(parts[0]); + versionRange.max = Version.parse(parts[1]); + return versionRange; + } + + public boolean contains(Version version) { + if (min != null) { + int result = min.compareTo(version); + if (result > 0) return false; + if (result == 0 && !leftInclusive) return false; + } + if (max != null) { + int result = max.compareTo(version); + if (result < 0) return false; + if (result == 0 && !rightInclusive) return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (leftInclusive) sb.append("["); + if (leftExclusive) sb.append("("); + if (min != null) sb.append(min); + sb.append(","); + if (max != null) sb.append(max); + if (rightInclusive) sb.append("]"); + if (rightExclusive) sb.append(")"); + return sb.toString(); + } +} diff --git a/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java b/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java new file mode 100644 index 00000000..43331817 --- /dev/null +++ b/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java @@ -0,0 +1,38 @@ +/* + * 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.dependencies.model; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +public class VersionRangeAdapter extends XmlAdapter { + + @Override + public VersionRange unmarshal(String v) throws Exception { + return VersionRange.parse(v); + } + + @Override + public String marshal(VersionRange v) throws Exception { + throw new UnsupportedOperationException(); + } + +} From dd95627811e0883f31991087552e080cd5119009 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Thu, 1 Feb 2024 21:20:38 +0100 Subject: [PATCH 39/65] Remove equals and now final hashCode method from test compilation unit hashCode is now final in the parent class, so we cannot override it. To avoid an NPE in the base implementation, we need to set the owner field. The PRIMARY working copy owner seems to be sufficient. --- test/core/src/lombok/RunTestsViaEcj.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index 8e9369e7..352ba4e6 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.java @@ -52,6 +52,7 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; +import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; import org.eclipse.jdt.internal.core.JavaModelManager; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -308,7 +309,7 @@ public class RunTestsViaEcj extends AbstractRunTests { private final char[] mainTypeName; private TestCompilationUnitEclipse(String name, String source) { - super(null, name, null); + super(null, name, DefaultWorkingCopyOwner.PRIMARY); this.source = source.toCharArray(); char[] fileNameCharArray = getFileName(); @@ -320,14 +321,6 @@ public class RunTestsViaEcj extends AbstractRunTests { mainTypeName = CharOperation.subarray(fileNameCharArray, start, end); } - @Override public int hashCode() { - return System.identityHashCode(this); - } - - @Override public boolean equals(Object obj) { - return this == obj; - } - @Override public char[] getContents() { return source; } From de4f6023bede61b446cc98f48538feb5f79374cb Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 2 Feb 2024 07:38:21 +0100 Subject: [PATCH 40/65] Update deprecated tasks --- .github/workflows/ant.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 2eb66be8..2022b3a6 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -10,16 +10,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: 11 - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ivyCache @@ -31,7 +31,7 @@ jobs: - name: Build with Ant run: ant -noinput dist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: lombok.jar path: dist/lombok.jar @@ -55,11 +55,11 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.jdk }} if: ${{ matrix.jdk < env.EA_JDK }} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.jdk }} distribution: 'zulu' @@ -82,7 +82,7 @@ jobs: echo "${HOME}/apache-ant-$ANT_VERSION/bin" >> $GITHUB_PATH - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ivyCache @@ -120,16 +120,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ivyCache @@ -140,7 +140,7 @@ jobs: - name: Cache base testenv if: ${{ !endsWith(matrix.version, 'full') }} - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | testenv @@ -148,7 +148,7 @@ jobs: - name: Cache full testenv if: ${{ endsWith(matrix.version, 'full') }} - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | testenv @@ -176,9 +176,9 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: lombok.jar From 3c59b40f1c300f20bbdfafb5411a7dc87dd46589 Mon Sep 17 00:00:00 2001 From: Emiliano Ruiz Carletti Date: Fri, 2 Feb 2024 13:52:58 -0300 Subject: [PATCH 41/65] Add arch x86_64 --- buildScripts/setup.ant.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index f8fb5e51..2ee4b787 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -55,6 +55,7 @@ This buildfile is part of projectlombok.org. It sets up the build itself. + From 496acffd7d451a73564b7cd993944cf30c454665 Mon Sep 17 00:00:00 2001 From: Ole Ludwig Date: Sun, 4 Feb 2024 15:21:01 +0100 Subject: [PATCH 42/65] Fix removal of SneakyThrows and PreventNullAnalysis from bytecode The SneakyThrowsRemover and PreventNullAnalysisRemover were leaving traces of the calls to lombok.Lombok.sneakyThrow and lombok.Lombok.preventNullAnalysis behind because they were using a constructor of ClassWriter which reuses the constant pool of the original class for performance optimizations. So although the calls to sneakyThrows and preventNullAnalysis get removed from the methods there were still entries in the constant pool for them. The constant pool will be regenerated with this change so that the entries for sneakyThrows and preventNullAnalysis gets removed. --- .../lombok/bytecode/FixedClassWriter.java | 6 +++- .../bytecode/PreventNullAnalysisRemover.java | 2 +- .../lombok/bytecode/SneakyThrowsRemover.java | 2 +- .../PostCompilePreventNullAnalysis.java | 15 ++++++++++ .../src/lombok/bytecode/TestPostCompiler.java | 28 ++++++++++++++++++- 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 test/bytecode/resource/PostCompilePreventNullAnalysis.java diff --git a/src/core/lombok/bytecode/FixedClassWriter.java b/src/core/lombok/bytecode/FixedClassWriter.java index f18dc3a4..6d86fe9d 100644 --- a/src/core/lombok/bytecode/FixedClassWriter.java +++ b/src/core/lombok/bytecode/FixedClassWriter.java @@ -28,6 +28,10 @@ class FixedClassWriter extends ClassWriter { FixedClassWriter(ClassReader classReader, int flags) { super(classReader, flags); } + + FixedClassWriter(int flags) { + super(flags); + } @Override protected String getCommonSuperClass(String type1, String type2) { //By default, ASM will attempt to live-load the class types, which will fail if meddling with classes in an @@ -40,4 +44,4 @@ class FixedClassWriter extends ClassWriter { return "java/lang/Object"; } } -} \ No newline at end of file +} diff --git a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java index 8ae7af5b..654a308a 100644 --- a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java +++ b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java @@ -44,7 +44,7 @@ public class PreventNullAnalysisRemover implements PostCompilerTransformation { byte[] fixedByteCode = fixJSRInlining(original); ClassReader reader = new ClassReader(fixedByteCode); - ClassWriter writer = new FixedClassWriter(reader, 0); + ClassWriter writer = new FixedClassWriter(0); final AtomicBoolean changesMade = new AtomicBoolean(); diff --git a/src/core/lombok/bytecode/SneakyThrowsRemover.java b/src/core/lombok/bytecode/SneakyThrowsRemover.java index ea1c3cec..b716245d 100644 --- a/src/core/lombok/bytecode/SneakyThrowsRemover.java +++ b/src/core/lombok/bytecode/SneakyThrowsRemover.java @@ -46,7 +46,7 @@ public class SneakyThrowsRemover implements PostCompilerTransformation { byte[] fixedByteCode = fixJSRInlining(original); ClassReader reader = new ClassReader(fixedByteCode); - ClassWriter writer = new ClassWriter(reader, 0); + ClassWriter writer = new ClassWriter(0); final AtomicBoolean changesMade = new AtomicBoolean(); diff --git a/test/bytecode/resource/PostCompilePreventNullAnalysis.java b/test/bytecode/resource/PostCompilePreventNullAnalysis.java new file mode 100644 index 00000000..0c9b387b --- /dev/null +++ b/test/bytecode/resource/PostCompilePreventNullAnalysis.java @@ -0,0 +1,15 @@ +public class PostCompilePreventNullAnalysis { + public void test() { + Object o = "Hello World!"; + try { + System.out.println(o); + } finally { + if (o != null) { + if (lombok.Lombok.preventNullAnalysis(o) != null) { + o.toString(); + } + } + } + } + +} diff --git a/test/bytecode/src/lombok/bytecode/TestPostCompiler.java b/test/bytecode/src/lombok/bytecode/TestPostCompiler.java index 2704ecec..3814e00d 100644 --- a/test/bytecode/src/lombok/bytecode/TestPostCompiler.java +++ b/test/bytecode/src/lombok/bytecode/TestPostCompiler.java @@ -33,7 +33,7 @@ import org.junit.Test; public class TestPostCompiler { @Test - public void testPostCompiler() throws IOException { + public void testPostCompilerSneakyThrows() { byte[] compiled = TestClassFileMetaData.compile(new File("test/bytecode/resource/PostCompileSneaky.java")); DiagnosticsReceiver receiver = new DiagnosticsReceiver() { @Override public void addWarning(String message) { @@ -50,5 +50,31 @@ public class TestPostCompiler { assertNotSame("Post-compiler did not do anything; we expected it to remove a Lombok.sneakyThrow() call.", compiled, transformed); assertTrue("After removing a sneakyThrow the classfile got... bigger (or stayed equal in size). Huh?", transformed.length < compiled.length); + + assertFalse("After post compilation, expected no lombok.Lombok.sneakyThrow() call in compiled code, but it's there", + new ClassFileMetaData(transformed).usesMethod("lombok/Lombok", "sneakyThrow")); + } + + @Test + public void testPostCompilerPreventNullAnalysis() { + byte[] compiled = TestClassFileMetaData.compile(new File("test/bytecode/resource/PostCompilePreventNullAnalysis.java")); + DiagnosticsReceiver receiver = new DiagnosticsReceiver() { + @Override public void addWarning(String message) { + fail("Warning during post compilation processing of a sneakyThrow call: " + message); + } + + @Override public void addError(String message) { + fail("Error during post compilation processing of a sneakyThrow call: " + message); + } + }; + assertTrue("Before post compilation, expected lombok.Lombok.preventNullAnalysis() call in compiled code, but it's not there", + new ClassFileMetaData(compiled).usesMethod("lombok/Lombok", "preventNullAnalysis")); + byte[] transformed = PostCompiler.applyTransformations(compiled, "PostCompilePreventNullAnalysis.java", receiver); + + assertNotSame("Post-compiler did not do anything; we expected it to remove a Lombok.preventNullAnalysis() call.", compiled, transformed); + assertTrue("After removing a sneakyThrow the classfile got... bigger (or stayed equal in size). Huh?", transformed.length < compiled.length); + + assertFalse("After post compilation, expected no lombok.Lombok.preventNullAnalysis() call in compiled code, but it's there", + new ClassFileMetaData(transformed).usesMethod("lombok/Lombok", "preventNullAnalysis")); } } From 04795298c182366f8716d0e79a44d995afccee24 Mon Sep 17 00:00:00 2001 From: Ole Ludwig Date: Wed, 7 Feb 2024 19:00:39 +0100 Subject: [PATCH 43/65] Update authors file --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index b291072f..71131764 100755 --- a/AUTHORS +++ b/AUTHORS @@ -34,6 +34,7 @@ Mateusz Matela Michael Dardis Michael Ernst Michiel Verheul +Ole Ludwig Pascal Bihler Peter Grant Philipp Eichhorn From c2e31dd8f702fb4f111ab44589de5fb4667b0d3c Mon Sep 17 00:00:00 2001 From: James Yoo <24359440+jyoo980@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:37:48 -0800 Subject: [PATCH 44/65] Add jspecify `@NonNull` annotation --- src/core/lombok/core/handlers/HandlerUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 07704aa8..f8308715 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -115,6 +115,7 @@ public class HandlerUtil { "org.eclipse.jdt.annotation.NonNull", "org.jetbrains.annotations.NotNull", "org.jmlspecs.annotation.NonNull", + "org.jspecify.annotations.NonNull", "org.netbeans.api.annotations.common.NonNull", "org.springframework.lang.NonNull", "reactor.util.annotation.NonNull", From 4a7c07df490e11737a59f60b4f553c2122ca5072 Mon Sep 17 00:00:00 2001 From: James Yoo <24359440+jyoo980@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:32:28 -0800 Subject: [PATCH 45/65] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 71131764..a4a0298d 100755 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ Denis Stepanov Emil Lundberg Enrique da Costa Cambio Jacob Middag +James Yoo Jan Matèrne Jan Rieke Jappe van der Hel From fee263fb8d631d01c3327b3c617e33fe36ae5b7b Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 22 Feb 2024 11:58:30 -0800 Subject: [PATCH 46/65] Update JSpecify annotation names --- src/core/lombok/core/handlers/HandlerUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 07704aa8..f02cbd37 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -185,8 +185,8 @@ public class HandlerUtil { "org.jetbrains.annotations.UnknownNullability", "org.jmlspecs.annotation.NonNull", "org.jmlspecs.annotation.Nullable", - "org.jspecify.nullness.Nullable", - "org.jspecify.nullness.NullnessUnspecified", + "org.jspecify.annotations.Nullable", + "org.jspecify.annotations.NonNull", "org.netbeans.api.annotations.common.CheckForNull", "org.netbeans.api.annotations.common.NonNull", "org.netbeans.api.annotations.common.NullAllowed", From 7904d5ae987e39ed99eed9593ae92d7901e6e346 Mon Sep 17 00:00:00 2001 From: James Yoo Date: Thu, 22 Feb 2024 12:11:56 -0800 Subject: [PATCH 47/65] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index a4a0298d..66b0c7d1 100755 --- a/AUTHORS +++ b/AUTHORS @@ -27,6 +27,7 @@ Kevin Chirls Liu DongMiao Luan Nico Maarten Mulders +Manu Sridharan Mark Haynes Mart Hagenaars Martin O'Connor <38929043+martinoconnor@users.noreply.github.com> From e78d1ac3c2108d850a33fb11a72a697b29aaf6b7 Mon Sep 17 00:00:00 2001 From: James Yoo Date: Thu, 22 Feb 2024 14:36:55 -0800 Subject: [PATCH 48/65] Update email for `@msridhar` --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 66b0c7d1..a8c9bcc4 100755 --- a/AUTHORS +++ b/AUTHORS @@ -27,7 +27,7 @@ Kevin Chirls Liu DongMiao Luan Nico Maarten Mulders -Manu Sridharan +Manu Sridharan Mark Haynes Mart Hagenaars Martin O'Connor <38929043+martinoconnor@users.noreply.github.com> From fc1c0186755fbc0d7d356ff697681feb7b2a18e7 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 18 Mar 2024 00:03:01 +0100 Subject: [PATCH 49/65] Use jdk22 GA instead of EA --- docker/provision/jdk/java-22.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/provision/jdk/java-22.sh b/docker/provision/jdk/java-22.sh index c442a6dc..69135bfd 100755 --- a/docker/provision/jdk/java-22.sh +++ b/docker/provision/jdk/java-22.sh @@ -1,4 +1,4 @@ apt-get update && apt-get install -y wget -wget https://download.java.net/java/early_access/jdk22/31/GPL/openjdk-22-ea+31_linux-x64_bin.tar.gz -O jdk.tar.gz +wget https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_linux-x64_bin.tar.gz -O jdk.tar.gz tar -xzf jdk.tar.gz -C /opt/ mv /opt/jdk-22 /opt/jdk From 566ef729491977adfd091bea3b59c8e1d8cc3189 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 1 Mar 2024 20:08:02 +0100 Subject: [PATCH 50/65] [fixes #3225] Handle ambiguous extension methods --- .../eclipse/agent/PatchExtensionMethod.java | 8 +++++--- .../ExtensionMethodAmbiguousFunctional.java | 17 ++++++++++++++++ .../ExtensionMethodAmbiguousFunctional.java | 20 +++++++++++++++++++ .../ExtensionMethodAmbiguousFunctional.java | 20 +++++++++++++++++++ ...ionMethodAmbiguousFunctional.java.messages | 1 + ...ionMethodAmbiguousFunctional.java.messages | 1 + 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java create mode 100644 test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java create mode 100644 test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java create mode 100644 test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages create mode 100644 test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java index 3b89c0af..555c84b0 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2023 The Project Lombok Authors. + * Copyright (C) 2012-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 @@ -321,9 +321,11 @@ public class PatchExtensionMethod { 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) { - PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope); + // Sometimes the declaring class is null, in that case we have to create a new ProblemMethodBinding using the extension method's declaring class + if (fixedBinding.declaringClass == null) { + fixedBinding = new ProblemMethodBinding(fixedBinding.selector, fixedBinding.parameters, extensionMethod.declaringClass, fixedBinding.problemId()); } + PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope); } else { // If the extension method uses varargs, the last fixed binding parameter is an array but // the method arguments are not. Even thought we already know that the method is fine we still diff --git a/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java new file mode 100644 index 00000000..8c93c03d --- /dev/null +++ b/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java @@ -0,0 +1,17 @@ +//skip-idempotent +import java.util.function.Consumer; +import java.util.function.Function; + +class ExtensionMethodAmbiguousFunctional { + public void test() { + ExtensionMethodAmbiguousFunctional.Extensions.ambiguous("", System.out::println); + } + + static class Extensions { + public static void ambiguous(T t, Function function) { + } + + public static void ambiguous(T t, Consumer function) { + } + } +} diff --git a/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java new file mode 100644 index 00000000..80d216b2 --- /dev/null +++ b/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java @@ -0,0 +1,20 @@ +import java.util.function.Consumer; +import java.util.function.Function; +import lombok.experimental.ExtensionMethod; +@ExtensionMethod({ExtensionMethodAmbiguousFunctional.Extensions.class}) class ExtensionMethodAmbiguousFunctional { + static class Extensions { + Extensions() { + super(); + } + public static void ambiguous(T t, Function function) { + } + public static void ambiguous(T t, Consumer function) { + } + } + ExtensionMethodAmbiguousFunctional() { + super(); + } + public void test() { + "".ambiguous(System.out::println); + } +} diff --git a/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java new file mode 100644 index 00000000..65c08404 --- /dev/null +++ b/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java @@ -0,0 +1,20 @@ +//version 8: +import java.util.function.Consumer; +import java.util.function.Function; + +import lombok.experimental.ExtensionMethod; + +@ExtensionMethod({ExtensionMethodAmbiguousFunctional.Extensions.class}) +class ExtensionMethodAmbiguousFunctional { + public void test() { + "".ambiguous(System.out::println); + } + + static class Extensions { + public static void ambiguous(T t, Function function) { + } + + public static void ambiguous(T t, Consumer function) { + } + } +} diff --git a/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages b/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages new file mode 100644 index 00000000..9fa3414f --- /dev/null +++ b/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages @@ -0,0 +1 @@ +9 reference to ambiguous is ambiguous both method ambiguous(T,java.util.function.Function) in ExtensionMethodAmbiguousFunctional.Extensions and method ambiguous(T,java.util.function.Consumer) in ExtensionMethodAmbiguousFunctional.Extensions match diff --git a/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages b/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages new file mode 100644 index 00000000..63e76c93 --- /dev/null +++ b/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages @@ -0,0 +1 @@ +10 The method ambiguous(String, Function) is ambiguous for the type ExtensionMethodAmbiguousFunctional.Extensions From 03201f2431705f8964f8b219df9405e486dd0997 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 1 Mar 2024 20:28:35 +0100 Subject: [PATCH 51/65] Always use maven to download ecj --- buildScripts/ivy.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index aa2643ed..c981c5fe 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -76,7 +76,7 @@ - + From e9c8c37566815de813f656adf763319e339a4e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Schl=C3=B6mer?= Date: Fri, 19 Jan 2024 14:35:54 +0100 Subject: [PATCH 52/65] [website] Fix typo on GetterSetter page --- website/templates/features/GetterSetter.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/features/GetterSetter.html b/website/templates/features/GetterSetter.html index 8b16d34d..8cf25ee4 100644 --- a/website/templates/features/GetterSetter.html +++ b/website/templates/features/GetterSetter.html @@ -28,7 +28,7 @@

lombok.accessors.fluent = [true | false] (default: false)
- If set to true, generated getters and setters will not be prefixed with the bean-standard 'get, is or set; instead, the methods will use the same name as the field (minus prefixes). An explicitly configured chain parameter of an @Accessors annotation takes precedence over this setting. + If set to true, generated getters and setters will not be prefixed with the bean-standard 'get, is or set; instead, the methods will use the same name as the field (minus prefixes). An explicitly configured fluent parameter of an @Accessors annotation takes precedence over this setting.
lombok.accessors.prefix += a field prefix (default: empty list)
From a54ec7005ed253d480621f042d923f3353e6a1d0 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 18 Mar 2024 00:29:47 +0100 Subject: [PATCH 53/65] Document using jdk22 GA --- docker/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/readme.md b/docker/readme.md index deb482f5..7bd05c64 100644 --- a/docker/readme.md +++ b/docker/readme.md @@ -13,7 +13,7 @@ By default, this is the latest released version. You can download a specific ver ### `ARG jdk=21` The jdk version to be used. Supported values: -- `22`(experimental, based on openjdk early access) +- `22`(based on openjdk GA) - `21` (default)(based on openjdk instead of adoptium) - `17` - `11` From 23307eb8d137d7e4a3f645552135ab7354ca1e6e Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Thu, 14 Mar 2024 20:28:26 +0100 Subject: [PATCH 54/65] [jdk22] Adds support for unnamed variables (JEP 456) --- .../lombok/delombok/PrettyPrinter.java | 12 +++- .../resource/after/UnnamedVariables.java | 70 +++++++++++++++++++ .../resource/before/UnnamedVariables.java | 70 +++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 test/pretty/resource/after/UnnamedVariables.java create mode 100644 test/pretty/resource/before/UnnamedVariables.java diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index d7434454..85598d32 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2021 The Project Lombok Authors. + * Copyright (C) 2016-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 @@ -263,6 +263,14 @@ public class PrettyPrinter extends JCTree.Visitor { return false; } + private void print(Name name) { + if (name.isEmpty()) { + print("_"); + } else { + print(name.toString()); + } + } + private void print(CharSequence s) { boolean align = needsAlign; if (needsNewLine && !onNewLine) println(); @@ -1722,6 +1730,8 @@ public class PrettyPrinter extends JCTree.Visitor { printPatternCaseLabel(tree); } else if (className.endsWith("$JCRecordPattern")) { // Introduced in JDK19 printRecordPattern(tree); + } else if (className.endsWith("$JCAnyPattern")) { // Introduced in JDK22 + print("_"); } else { throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree); } diff --git a/test/pretty/resource/after/UnnamedVariables.java b/test/pretty/resource/after/UnnamedVariables.java new file mode 100644 index 00000000..f95b29ca --- /dev/null +++ b/test/pretty/resource/after/UnnamedVariables.java @@ -0,0 +1,70 @@ +// version 22: +import java.util.Arrays; +import java.util.Scanner; +import java.util.stream.Stream; + +record Box(T content) { +} + +record Pair(T first, U second) { +} + +public class UnnamedVariables { + void enhancedLoop() { + for (String _ : Arrays.asList("")) { + } + } + + void initializationInForLoop() { + for (int i = 0, _ = Integer.MAX_VALUE; i < 10; i++) { + } + } + + void assignment() { + var _ = 1; + } + + void catchBlock() { + try { + } catch (Exception _) { + } + } + + void tryWithResources() { + try (var _ = new Scanner("")) { + } + } + + void lambda() { + Stream.of(1).forEach(_ -> { + }); + } + + Object switchStatement(Object o) { + return switch (o) { + case String _, Integer _ -> o; + case Long _ -> o; + default -> o; + }; + } + + void recordPattern(Object o) { + if (o instanceof Pair(Box _, Box(Integer _))) { + } + if (o instanceof Box(String _)) { + } + if (o instanceof Box(var _)) { + } + if (o instanceof Box(_)) { + } + } + + Object recordPatternSwitch(Object o) { + return switch (o) { + case Box(String _), Box(Integer _) -> o; + case Box(Long _) -> o; + case Box(_) -> o; + default -> o; + }; + } +} diff --git a/test/pretty/resource/before/UnnamedVariables.java b/test/pretty/resource/before/UnnamedVariables.java new file mode 100644 index 00000000..f95b29ca --- /dev/null +++ b/test/pretty/resource/before/UnnamedVariables.java @@ -0,0 +1,70 @@ +// version 22: +import java.util.Arrays; +import java.util.Scanner; +import java.util.stream.Stream; + +record Box(T content) { +} + +record Pair(T first, U second) { +} + +public class UnnamedVariables { + void enhancedLoop() { + for (String _ : Arrays.asList("")) { + } + } + + void initializationInForLoop() { + for (int i = 0, _ = Integer.MAX_VALUE; i < 10; i++) { + } + } + + void assignment() { + var _ = 1; + } + + void catchBlock() { + try { + } catch (Exception _) { + } + } + + void tryWithResources() { + try (var _ = new Scanner("")) { + } + } + + void lambda() { + Stream.of(1).forEach(_ -> { + }); + } + + Object switchStatement(Object o) { + return switch (o) { + case String _, Integer _ -> o; + case Long _ -> o; + default -> o; + }; + } + + void recordPattern(Object o) { + if (o instanceof Pair(Box _, Box(Integer _))) { + } + if (o instanceof Box(String _)) { + } + if (o instanceof Box(var _)) { + } + if (o instanceof Box(_)) { + } + } + + Object recordPatternSwitch(Object o) { + return switch (o) { + case Box(String _), Box(Integer _) -> o; + case Box(Long _) -> o; + case Box(_) -> o; + default -> o; + }; + } +} From c93400d9f44b1e06aa3763c4a2818e43b70f3630 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 14 Jan 2024 10:58:47 +0100 Subject: [PATCH 55/65] [fixes #2917] Use $value instead of value in lazy getter --- .../lombok/eclipse/handlers/HandleGetter.java | 4 +- .../lombok/javac/handlers/HandleGetter.java | 4 +- .../after-delombok/DelegateOnGetter.java | 14 +- .../resource/after-delombok/GetterLazy.java | 14 +- .../after-delombok/GetterLazyArguments.java | 84 ++++++------ .../after-delombok/GetterLazyBoolean.java | 28 ++-- .../GetterLazyEahcToString.java | 14 +- .../GetterLazyErrorPosition.java | 14 +- .../after-delombok/GetterLazyGenerics.java | 28 ++-- .../GetterLazyInAnonymousClass.java | 14 +- .../after-delombok/GetterLazyNative.java | 126 +++++++++--------- .../after-delombok/GetterLazyTransient.java | 14 +- .../after-delombok/SkipSuppressWarnings.java | 14 +- .../resource/after-ecj/DelegateOnGetter.java | 14 +- .../resource/after-ecj/GetterLazy.java | 14 +- .../after-ecj/GetterLazyArguments.java | 84 ++++++------ .../resource/after-ecj/GetterLazyBoolean.java | 28 ++-- .../after-ecj/GetterLazyEahcToString.java | 14 +- .../after-ecj/GetterLazyGenerics.java | 28 ++-- .../after-ecj/GetterLazyInAnonymousClass.java | 14 +- .../resource/after-ecj/GetterLazyNative.java | 126 +++++++++--------- .../after-ecj/GetterLazyTransient.java | 14 +- .../after-ecj/SkipSuppressWarnings.java | 14 +- 23 files changed, 361 insertions(+), 361 deletions(-) diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 2d8b112f..5ed2c2d9 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2022 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -323,7 +323,7 @@ public class HandleGetter extends EclipseAnnotationHandler { TYPE_MAP = Collections.unmodifiableMap(m); } - private static char[] valueName = "value".toCharArray(); + private static char[] valueName = "$value".toCharArray(); private static char[] actualValueName = "actualValue".toCharArray(); private static final int PARENTHESIZED = (1 << ASTNode.ParenthesizedSHIFT) & ASTNode.ParenthesizedMASK; diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 153a2201..dac524dd 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2022 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -358,7 +358,7 @@ public class HandleGetter extends JavacAnnotationHandler { } if (copyOfBoxedFieldType == null) copyOfBoxedFieldType = copyType(maker, field, source); - Name valueName = fieldNode.toName("value"); + Name valueName = fieldNode.toName("$value"); Name actualValueName = fieldNode.toName("actualValue"); /* java.lang.Object value = this.fieldName.get();*/ { diff --git a/test/transform/resource/after-delombok/DelegateOnGetter.java b/test/transform/resource/after-delombok/DelegateOnGetter.java index edf1641b..76794085 100644 --- a/test/transform/resource/after-delombok/DelegateOnGetter.java +++ b/test/transform/resource/after-delombok/DelegateOnGetter.java @@ -6,11 +6,11 @@ class DelegateOnGetter { } @java.lang.SuppressWarnings({"all", "unchecked"}) public Bar getBar() { - java.lang.Object value = this.bar.get(); - if (value == null) { + java.lang.Object $value = this.bar.get(); + if ($value == null) { synchronized (this.bar) { - value = this.bar.get(); - if (value == null) { + $value = this.bar.get(); + if ($value == null) { final Bar actualValue = new Bar() { public void setList(java.util.ArrayList list) { } @@ -18,12 +18,12 @@ class DelegateOnGetter { return 42; } }; - value = actualValue == null ? this.bar : actualValue; - this.bar.set(value); + $value = actualValue == null ? this.bar : actualValue; + this.bar.set($value); } } } - return (Bar) (value == this.bar ? null : value); + return (Bar) ($value == this.bar ? null : $value); } @java.lang.SuppressWarnings("all") public void setList(final java.util.ArrayList list) { diff --git a/test/transform/resource/after-delombok/GetterLazy.java b/test/transform/resource/after-delombok/GetterLazy.java index 1e30f94b..8e1300be 100644 --- a/test/transform/resource/after-delombok/GetterLazy.java +++ b/test/transform/resource/after-delombok/GetterLazy.java @@ -4,17 +4,17 @@ class GetterLazy { private final java.util.concurrent.atomic.AtomicReference fieldName = new java.util.concurrent.atomic.AtomicReference(); @java.lang.SuppressWarnings({"all", "unchecked"}) public ValueType getFieldName() { - java.lang.Object value = this.fieldName.get(); - if (value == null) { + java.lang.Object $value = this.fieldName.get(); + if ($value == null) { synchronized (this.fieldName) { - value = this.fieldName.get(); - if (value == null) { + $value = this.fieldName.get(); + if ($value == null) { final ValueType actualValue = new ValueType(); - value = actualValue == null ? this.fieldName : actualValue; - this.fieldName.set(value); + $value = actualValue == null ? this.fieldName : actualValue; + this.fieldName.set($value); } } } - return (ValueType) (value == this.fieldName ? null : value); + return (ValueType) ($value == this.fieldName ? null : $value); } } diff --git a/test/transform/resource/after-delombok/GetterLazyArguments.java b/test/transform/resource/after-delombok/GetterLazyArguments.java index ef3f341c..00b17f5c 100644 --- a/test/transform/resource/after-delombok/GetterLazyArguments.java +++ b/test/transform/resource/after-delombok/GetterLazyArguments.java @@ -21,99 +21,99 @@ class GetterLazyArguments { @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField1() { - java.lang.Object value = this.field1.get(); - if (value == null) { + java.lang.Object $value = this.field1.get(); + if ($value == null) { synchronized (this.field1) { - value = this.field1.get(); - if (value == null) { + $value = this.field1.get(); + if ($value == null) { final String actualValue = stringInt(("a"), (1)); - value = actualValue == null ? this.field1 : actualValue; - this.field1.set(value); + $value = actualValue == null ? this.field1 : actualValue; + this.field1.set($value); } } } - return (String) (value == this.field1 ? null : value); + return (String) ($value == this.field1 ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField2() { - java.lang.Object value = this.field2.get(); - if (value == null) { + java.lang.Object $value = this.field2.get(); + if ($value == null) { synchronized (this.field2) { - value = this.field2.get(); - if (value == null) { + $value = this.field2.get(); + if ($value == null) { final String actualValue = stringInt(true ? "a" : "b", true ? 1 : 0); - value = actualValue == null ? this.field2 : actualValue; - this.field2.set(value); + $value = actualValue == null ? this.field2 : actualValue; + this.field2.set($value); } } } - return (String) (value == this.field2 ? null : value); + return (String) ($value == this.field2 ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField3() { - java.lang.Object value = this.field3.get(); - if (value == null) { + java.lang.Object $value = this.field3.get(); + if ($value == null) { synchronized (this.field3) { - value = this.field3.get(); - if (value == null) { + $value = this.field3.get(); + if ($value == null) { final String actualValue = stringInt(("a"), true ? 1 : 0); - value = actualValue == null ? this.field3 : actualValue; - this.field3.set(value); + $value = actualValue == null ? this.field3 : actualValue; + this.field3.set($value); } } } - return (String) (value == this.field3 ? null : value); + return (String) ($value == this.field3 ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField4() { - java.lang.Object value = this.field4.get(); - if (value == null) { + java.lang.Object $value = this.field4.get(); + if ($value == null) { synchronized (this.field4) { - value = this.field4.get(); - if (value == null) { + $value = this.field4.get(); + if ($value == null) { final String actualValue = stringRunnable(fun(), () -> { }); - value = actualValue == null ? this.field4 : actualValue; - this.field4.set(value); + $value = actualValue == null ? this.field4 : actualValue; + this.field4.set($value); } } } - return (String) (value == this.field4 ? null : value); + return (String) ($value == this.field4 ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField5() { - java.lang.Object value = this.field5.get(); - if (value == null) { + java.lang.Object $value = this.field5.get(); + if ($value == null) { synchronized (this.field5) { - value = this.field5.get(); - if (value == null) { + $value = this.field5.get(); + if ($value == null) { final String actualValue = stringRunnable(("a"), () -> { }); - value = actualValue == null ? this.field5 : actualValue; - this.field5.set(value); + $value = actualValue == null ? this.field5 : actualValue; + this.field5.set($value); } } } - return (String) (value == this.field5 ? null : value); + return (String) ($value == this.field5 ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField6() { - java.lang.Object value = this.field6.get(); - if (value == null) { + java.lang.Object $value = this.field6.get(); + if ($value == null) { synchronized (this.field6) { - value = this.field6.get(); - if (value == null) { + $value = this.field6.get(); + if ($value == null) { final String actualValue = true ? stringInt(true ? "a" : "b", true ? 1 : 0) : ""; - value = actualValue == null ? this.field6 : actualValue; - this.field6.set(value); + $value = actualValue == null ? this.field6 : actualValue; + this.field6.set($value); } } } - return (String) (value == this.field6 ? null : value); + return (String) ($value == this.field6 ? null : $value); } } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/GetterLazyBoolean.java b/test/transform/resource/after-delombok/GetterLazyBoolean.java index 5b1f19dc..495e6b92 100644 --- a/test/transform/resource/after-delombok/GetterLazyBoolean.java +++ b/test/transform/resource/after-delombok/GetterLazyBoolean.java @@ -33,32 +33,32 @@ class GetterLazyBoolean { } @java.lang.SuppressWarnings({"all", "unchecked"}) public boolean isBooleanValue() { - java.lang.Object value = this.booleanValue.get(); - if (value == null) { + java.lang.Object $value = this.booleanValue.get(); + if ($value == null) { synchronized (this.booleanValue) { - value = this.booleanValue.get(); - if (value == null) { + $value = this.booleanValue.get(); + if ($value == null) { final boolean actualValue = calculateBoolean(); - value = actualValue; - this.booleanValue.set(value); + $value = actualValue; + this.booleanValue.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public boolean isOtherBooleanValue() { - java.lang.Object value = this.otherBooleanValue.get(); - if (value == null) { + java.lang.Object $value = this.otherBooleanValue.get(); + if ($value == null) { synchronized (this.otherBooleanValue) { - value = this.otherBooleanValue.get(); - if (value == null) { + $value = this.otherBooleanValue.get(); + if ($value == null) { final boolean actualValue = !calculateBoolean(); - value = actualValue; - this.otherBooleanValue.set(value); + $value = actualValue; + this.otherBooleanValue.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } } diff --git a/test/transform/resource/after-delombok/GetterLazyEahcToString.java b/test/transform/resource/after-delombok/GetterLazyEahcToString.java index bec89818..3742093b 100644 --- a/test/transform/resource/after-delombok/GetterLazyEahcToString.java +++ b/test/transform/resource/after-delombok/GetterLazyEahcToString.java @@ -46,18 +46,18 @@ class GetterLazyEahcToString { @java.lang.SuppressWarnings({"all", "unchecked"}) public String getValue() { - java.lang.Object value = this.value.get(); - if (value == null) { + java.lang.Object $value = this.value.get(); + if ($value == null) { synchronized (this.value) { - value = this.value.get(); - if (value == null) { + $value = this.value.get(); + if ($value == null) { final String actualValue = ""; - value = actualValue == null ? this.value : actualValue; - this.value.set(value); + $value = actualValue == null ? this.value : actualValue; + this.value.set($value); } } } - return (String) (value == this.value ? null : value); + return (String) ($value == this.value ? null : $value); } @java.lang.SuppressWarnings("all") diff --git a/test/transform/resource/after-delombok/GetterLazyErrorPosition.java b/test/transform/resource/after-delombok/GetterLazyErrorPosition.java index 76797d44..c9013876 100644 --- a/test/transform/resource/after-delombok/GetterLazyErrorPosition.java +++ b/test/transform/resource/after-delombok/GetterLazyErrorPosition.java @@ -3,17 +3,17 @@ class GetterLazyErrorPosition { @java.lang.SuppressWarnings({"all", "unchecked"}) public String getField() { - java.lang.Object value = this.field.get(); - if (value == null) { + java.lang.Object $value = this.field.get(); + if ($value == null) { synchronized (this.field) { - value = this.field.get(); - if (value == null) { + $value = this.field.get(); + if ($value == null) { final String actualValue = true ? "" : new ErrorPosition(); - value = actualValue == null ? this.field : actualValue; - this.field.set(value); + $value = actualValue == null ? this.field : actualValue; + this.field.set($value); } } } - return (String) (value == this.field ? null : value); + return (String) ($value == this.field ? null : $value); } } diff --git a/test/transform/resource/after-delombok/GetterLazyGenerics.java b/test/transform/resource/after-delombok/GetterLazyGenerics.java index 5e92cda7..a8b8ff6c 100644 --- a/test/transform/resource/after-delombok/GetterLazyGenerics.java +++ b/test/transform/resource/after-delombok/GetterLazyGenerics.java @@ -6,32 +6,32 @@ class GetterLazyGenerics { } @java.lang.SuppressWarnings({"all", "unchecked"}) public E getField() { - java.lang.Object value = this.field.get(); - if (value == null) { + java.lang.Object $value = this.field.get(); + if ($value == null) { synchronized (this.field) { - value = this.field.get(); - if (value == null) { + $value = this.field.get(); + if ($value == null) { final E actualValue = getAny(); - value = actualValue == null ? this.field : actualValue; - this.field.set(value); + $value = actualValue == null ? this.field : actualValue; + this.field.set($value); } } } - return (E) (value == this.field ? null : value); + return (E) ($value == this.field ? null : $value); } @java.lang.SuppressWarnings({"all", "unchecked"}) public long getField2() { - java.lang.Object value = this.field2.get(); - if (value == null) { + java.lang.Object $value = this.field2.get(); + if ($value == null) { synchronized (this.field2) { - value = this.field2.get(); - if (value == null) { + $value = this.field2.get(); + if ($value == null) { final long actualValue = System.currentTimeMillis(); - value = actualValue; - this.field2.set(value); + $value = actualValue; + this.field2.set($value); } } } - return (java.lang.Long) value; + return (java.lang.Long) $value; } } \ No newline at end of file diff --git a/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java b/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java index 4476e463..199437a1 100644 --- a/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java +++ b/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java @@ -6,18 +6,18 @@ public class GetterLazyInAnonymousClass { @java.lang.SuppressWarnings({"all", "unchecked"}) public String getString() { - java.lang.Object value = this.string.get(); - if (value == null) { + java.lang.Object $value = this.string.get(); + if ($value == null) { synchronized (this.string) { - value = this.string.get(); - if (value == null) { + $value = this.string.get(); + if ($value == null) { final String actualValue = "test"; - value = actualValue == null ? this.string : actualValue; - this.string.set(value); + $value = actualValue == null ? this.string : actualValue; + this.string.set($value); } } } - return (String) (value == this.string ? null : value); + return (String) ($value == this.string ? null : $value); } } }; diff --git a/test/transform/resource/after-delombok/GetterLazyNative.java b/test/transform/resource/after-delombok/GetterLazyNative.java index f43d5490..a71a0354 100644 --- a/test/transform/resource/after-delombok/GetterLazyNative.java +++ b/test/transform/resource/after-delombok/GetterLazyNative.java @@ -10,137 +10,137 @@ class GetterLazyNative { private final java.util.concurrent.atomic.AtomicReference intArrayField = new java.util.concurrent.atomic.AtomicReference(); @java.lang.SuppressWarnings({"all", "unchecked"}) public boolean isBooleanField() { - java.lang.Object value = this.booleanField.get(); - if (value == null) { + java.lang.Object $value = this.booleanField.get(); + if ($value == null) { synchronized (this.booleanField) { - value = this.booleanField.get(); - if (value == null) { + $value = this.booleanField.get(); + if ($value == null) { final boolean actualValue = true; - value = actualValue; - this.booleanField.set(value); + $value = actualValue; + this.booleanField.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public byte getByteField() { - java.lang.Object value = this.byteField.get(); - if (value == null) { + java.lang.Object $value = this.byteField.get(); + if ($value == null) { synchronized (this.byteField) { - value = this.byteField.get(); - if (value == null) { + $value = this.byteField.get(); + if ($value == null) { final byte actualValue = 1; - value = actualValue; - this.byteField.set(value); + $value = actualValue; + this.byteField.set($value); } } } - return (java.lang.Byte) value; + return (java.lang.Byte) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public short getShortField() { - java.lang.Object value = this.shortField.get(); - if (value == null) { + java.lang.Object $value = this.shortField.get(); + if ($value == null) { synchronized (this.shortField) { - value = this.shortField.get(); - if (value == null) { + $value = this.shortField.get(); + if ($value == null) { final short actualValue = 1; - value = actualValue; - this.shortField.set(value); + $value = actualValue; + this.shortField.set($value); } } } - return (java.lang.Short) value; + return (java.lang.Short) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public int getIntField() { - java.lang.Object value = this.intField.get(); - if (value == null) { + java.lang.Object $value = this.intField.get(); + if ($value == null) { synchronized (this.intField) { - value = this.intField.get(); - if (value == null) { + $value = this.intField.get(); + if ($value == null) { final int actualValue = 1; - value = actualValue; - this.intField.set(value); + $value = actualValue; + this.intField.set($value); } } } - return (java.lang.Integer) value; + return (java.lang.Integer) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public long getLongField() { - java.lang.Object value = this.longField.get(); - if (value == null) { + java.lang.Object $value = this.longField.get(); + if ($value == null) { synchronized (this.longField) { - value = this.longField.get(); - if (value == null) { + $value = this.longField.get(); + if ($value == null) { final long actualValue = 1; - value = actualValue; - this.longField.set(value); + $value = actualValue; + this.longField.set($value); } } } - return (java.lang.Long) value; + return (java.lang.Long) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public float getFloatField() { - java.lang.Object value = this.floatField.get(); - if (value == null) { + java.lang.Object $value = this.floatField.get(); + if ($value == null) { synchronized (this.floatField) { - value = this.floatField.get(); - if (value == null) { + $value = this.floatField.get(); + if ($value == null) { final float actualValue = 1.0F; - value = actualValue; - this.floatField.set(value); + $value = actualValue; + this.floatField.set($value); } } } - return (java.lang.Float) value; + return (java.lang.Float) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public double getDoubleField() { - java.lang.Object value = this.doubleField.get(); - if (value == null) { + java.lang.Object $value = this.doubleField.get(); + if ($value == null) { synchronized (this.doubleField) { - value = this.doubleField.get(); - if (value == null) { + $value = this.doubleField.get(); + if ($value == null) { final double actualValue = 1.0; - value = actualValue; - this.doubleField.set(value); + $value = actualValue; + this.doubleField.set($value); } } } - return (java.lang.Double) value; + return (java.lang.Double) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public char getCharField() { - java.lang.Object value = this.charField.get(); - if (value == null) { + java.lang.Object $value = this.charField.get(); + if ($value == null) { synchronized (this.charField) { - value = this.charField.get(); - if (value == null) { + $value = this.charField.get(); + if ($value == null) { final char actualValue = '1'; - value = actualValue; - this.charField.set(value); + $value = actualValue; + this.charField.set($value); } } } - return (java.lang.Character) value; + return (java.lang.Character) $value; } @java.lang.SuppressWarnings({"all", "unchecked"}) public int[] getIntArrayField() { - java.lang.Object value = this.intArrayField.get(); - if (value == null) { + java.lang.Object $value = this.intArrayField.get(); + if ($value == null) { synchronized (this.intArrayField) { - value = this.intArrayField.get(); - if (value == null) { + $value = this.intArrayField.get(); + if ($value == null) { final int[] actualValue = new int[] {1}; - value = actualValue == null ? this.intArrayField : actualValue; - this.intArrayField.set(value); + $value = actualValue == null ? this.intArrayField : actualValue; + this.intArrayField.set($value); } } } - return (int[]) (value == this.intArrayField ? null : value); + return (int[]) ($value == this.intArrayField ? null : $value); } } diff --git a/test/transform/resource/after-delombok/GetterLazyTransient.java b/test/transform/resource/after-delombok/GetterLazyTransient.java index 0fd85621..3d1a2be3 100644 --- a/test/transform/resource/after-delombok/GetterLazyTransient.java +++ b/test/transform/resource/after-delombok/GetterLazyTransient.java @@ -4,18 +4,18 @@ class GetterLazyTransient { private final transient int nonLazyTransientField = 3; @java.lang.SuppressWarnings({"all", "unchecked"}) public int getNonTransientField() { - java.lang.Object value = this.nonTransientField.get(); - if (value == null) { + java.lang.Object $value = this.nonTransientField.get(); + if ($value == null) { synchronized (this.nonTransientField) { - value = this.nonTransientField.get(); - if (value == null) { + $value = this.nonTransientField.get(); + if ($value == null) { final int actualValue = 1; - value = actualValue; - this.nonTransientField.set(value); + $value = actualValue; + this.nonTransientField.set($value); } } } - return (java.lang.Integer) value; + return (java.lang.Integer) $value; } @java.lang.SuppressWarnings("all") public int getNonLazyTransientField() { diff --git a/test/transform/resource/after-delombok/SkipSuppressWarnings.java b/test/transform/resource/after-delombok/SkipSuppressWarnings.java index 151d4e17..77bfdcc4 100644 --- a/test/transform/resource/after-delombok/SkipSuppressWarnings.java +++ b/test/transform/resource/after-delombok/SkipSuppressWarnings.java @@ -8,17 +8,17 @@ class SkipSuppressWarnings { @java.lang.SuppressWarnings({"unchecked"}) public String getField2() { - java.lang.Object value = this.field2.get(); - if (value == null) { + java.lang.Object $value = this.field2.get(); + if ($value == null) { synchronized (this.field2) { - value = this.field2.get(); - if (value == null) { + $value = this.field2.get(); + if ($value == null) { final String actualValue = ""; - value = actualValue == null ? this.field2 : actualValue; - this.field2.set(value); + $value = actualValue == null ? this.field2 : actualValue; + this.field2.set($value); } } } - return (String) (value == this.field2 ? null : value); + return (String) ($value == this.field2 ? null : $value); } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/DelegateOnGetter.java b/test/transform/resource/after-ecj/DelegateOnGetter.java index f2b9a6cd..c23ea917 100644 --- a/test/transform/resource/after-ecj/DelegateOnGetter.java +++ b/test/transform/resource/after-ecj/DelegateOnGetter.java @@ -10,13 +10,13 @@ class DelegateOnGetter { super(); } public @Delegate @java.lang.SuppressWarnings({"all", "unchecked"}) Bar getBar() { - java.lang.Object value = this.bar.get(); - if ((value == null)) + java.lang.Object $value = this.bar.get(); + if (($value == null)) { synchronized (this.bar) { - value = this.bar.get(); - if ((value == null)) + $value = this.bar.get(); + if (($value == null)) { final Bar actualValue = new Bar() { x() { @@ -28,12 +28,12 @@ class DelegateOnGetter { return 42; } }; - value = ((actualValue == null) ? this.bar : actualValue); - this.bar.set(value); + $value = ((actualValue == null) ? this.bar : actualValue); + this.bar.set($value); } } } - return (Bar) ((value == this.bar) ? null : value); + return (Bar) (($value == this.bar) ? null : $value); } public @java.lang.SuppressWarnings("all") int getInt() { return this.getBar().getInt(); diff --git a/test/transform/resource/after-ecj/GetterLazy.java b/test/transform/resource/after-ecj/GetterLazy.java index b4567f04..7627ab16 100644 --- a/test/transform/resource/after-ecj/GetterLazy.java +++ b/test/transform/resource/after-ecj/GetterLazy.java @@ -9,20 +9,20 @@ class GetterLazy { super(); } public @java.lang.SuppressWarnings({"all", "unchecked"}) ValueType getFieldName() { - java.lang.Object value = this.fieldName.get(); - if ((value == null)) + java.lang.Object $value = this.fieldName.get(); + if (($value == null)) { synchronized (this.fieldName) { - value = this.fieldName.get(); - if ((value == null)) + $value = this.fieldName.get(); + if (($value == null)) { final ValueType actualValue = new ValueType(); - value = ((actualValue == null) ? this.fieldName : actualValue); - this.fieldName.set(value); + $value = ((actualValue == null) ? this.fieldName : actualValue); + this.fieldName.set($value); } } } - return (ValueType) ((value == this.fieldName) ? null : value); + return (ValueType) (($value == this.fieldName) ? null : $value); } } diff --git a/test/transform/resource/after-ecj/GetterLazyArguments.java b/test/transform/resource/after-ecj/GetterLazyArguments.java index 14086d81..bb51c4fc 100644 --- a/test/transform/resource/after-ecj/GetterLazyArguments.java +++ b/test/transform/resource/after-ecj/GetterLazyArguments.java @@ -18,107 +18,107 @@ class GetterLazyArguments { return null; } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField1() { - java.lang.Object value = this.field1.get(); - if ((value == null)) + java.lang.Object $value = this.field1.get(); + if (($value == null)) { synchronized (this.field1) { - value = this.field1.get(); - if ((value == null)) + $value = this.field1.get(); + if (($value == null)) { final String actualValue = stringInt("a", 1); - value = ((actualValue == null) ? this.field1 : actualValue); - this.field1.set(value); + $value = ((actualValue == null) ? this.field1 : actualValue); + this.field1.set($value); } } } - return (String) ((value == this.field1) ? null : value); + return (String) (($value == this.field1) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField2() { - java.lang.Object value = this.field2.get(); - if ((value == null)) + java.lang.Object $value = this.field2.get(); + if (($value == null)) { synchronized (this.field2) { - value = this.field2.get(); - if ((value == null)) + $value = this.field2.get(); + if (($value == null)) { final String actualValue = stringInt((true ? "a" : "b"), (true ? 1 : 0)); - value = ((actualValue == null) ? this.field2 : actualValue); - this.field2.set(value); + $value = ((actualValue == null) ? this.field2 : actualValue); + this.field2.set($value); } } } - return (String) ((value == this.field2) ? null : value); + return (String) (($value == this.field2) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField3() { - java.lang.Object value = this.field3.get(); - if ((value == null)) + java.lang.Object $value = this.field3.get(); + if (($value == null)) { synchronized (this.field3) { - value = this.field3.get(); - if ((value == null)) + $value = this.field3.get(); + if (($value == null)) { final String actualValue = stringInt("a", (true ? 1 : 0)); - value = ((actualValue == null) ? this.field3 : actualValue); - this.field3.set(value); + $value = ((actualValue == null) ? this.field3 : actualValue); + this.field3.set($value); } } } - return (String) ((value == this.field3) ? null : value); + return (String) (($value == this.field3) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField4() { - java.lang.Object value = this.field4.get(); - if ((value == null)) + java.lang.Object $value = this.field4.get(); + if (($value == null)) { synchronized (this.field4) { - value = this.field4.get(); - if ((value == null)) + $value = this.field4.get(); + if (($value == null)) { final String actualValue = stringRunnable(fun(), () -> { }); - value = ((actualValue == null) ? this.field4 : actualValue); - this.field4.set(value); + $value = ((actualValue == null) ? this.field4 : actualValue); + this.field4.set($value); } } } - return (String) ((value == this.field4) ? null : value); + return (String) (($value == this.field4) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField5() { - java.lang.Object value = this.field5.get(); - if ((value == null)) + java.lang.Object $value = this.field5.get(); + if (($value == null)) { synchronized (this.field5) { - value = this.field5.get(); - if ((value == null)) + $value = this.field5.get(); + if (($value == null)) { final String actualValue = stringRunnable("a", () -> { }); - value = ((actualValue == null) ? this.field5 : actualValue); - this.field5.set(value); + $value = ((actualValue == null) ? this.field5 : actualValue); + this.field5.set($value); } } } - return (String) ((value == this.field5) ? null : value); + return (String) (($value == this.field5) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField6() { - java.lang.Object value = this.field6.get(); - if ((value == null)) + java.lang.Object $value = this.field6.get(); + if (($value == null)) { synchronized (this.field6) { - value = this.field6.get(); - if ((value == null)) + $value = this.field6.get(); + if (($value == null)) { final String actualValue = (true ? stringInt((true ? "a" : "b"), (true ? 1 : 0)) : ""); - value = ((actualValue == null) ? this.field6 : actualValue); - this.field6.set(value); + $value = ((actualValue == null) ? this.field6 : actualValue); + this.field6.set($value); } } } - return (String) ((value == this.field6) ? null : value); + return (String) (($value == this.field6) ? null : $value); } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/GetterLazyBoolean.java b/test/transform/resource/after-ecj/GetterLazyBoolean.java index ad319755..40ecb856 100644 --- a/test/transform/resource/after-ecj/GetterLazyBoolean.java +++ b/test/transform/resource/after-ecj/GetterLazyBoolean.java @@ -8,38 +8,38 @@ return true; } public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isBooleanValue() { - java.lang.Object value = this.booleanValue.get(); - if ((value == null)) + java.lang.Object $value = this.booleanValue.get(); + if (($value == null)) { synchronized (this.booleanValue) { - value = this.booleanValue.get(); - if ((value == null)) + $value = this.booleanValue.get(); + if (($value == null)) { final boolean actualValue = calculateBoolean(); - value = actualValue; - this.booleanValue.set(value); + $value = actualValue; + this.booleanValue.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isOtherBooleanValue() { - java.lang.Object value = this.otherBooleanValue.get(); - if ((value == null)) + java.lang.Object $value = this.otherBooleanValue.get(); + if (($value == null)) { synchronized (this.otherBooleanValue) { - value = this.otherBooleanValue.get(); - if ((value == null)) + $value = this.otherBooleanValue.get(); + if (($value == null)) { final boolean actualValue = (! calculateBoolean()); - value = actualValue; - this.otherBooleanValue.set(value); + $value = actualValue; + this.otherBooleanValue.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { if ((o == this)) diff --git a/test/transform/resource/after-ecj/GetterLazyEahcToString.java b/test/transform/resource/after-ecj/GetterLazyEahcToString.java index 5197f4e1..f4f4ed37 100644 --- a/test/transform/resource/after-ecj/GetterLazyEahcToString.java +++ b/test/transform/resource/after-ecj/GetterLazyEahcToString.java @@ -5,21 +5,21 @@ super(); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getValue() { - java.lang.Object value = this.value.get(); - if ((value == null)) + java.lang.Object $value = this.value.get(); + if (($value == null)) { synchronized (this.value) { - value = this.value.get(); - if ((value == null)) + $value = this.value.get(); + if (($value == null)) { final String actualValue = ""; - value = ((actualValue == null) ? this.value : actualValue); - this.value.set(value); + $value = ((actualValue == null) ? this.value : actualValue); + this.value.set($value); } } } - return (String) ((value == this.value) ? null : value); + return (String) (($value == this.value) ? null : $value); } public @java.lang.SuppressWarnings("all") String getValue2() { return this.value2; diff --git a/test/transform/resource/after-ecj/GetterLazyGenerics.java b/test/transform/resource/after-ecj/GetterLazyGenerics.java index 67ef5543..3a2a06c1 100644 --- a/test/transform/resource/after-ecj/GetterLazyGenerics.java +++ b/test/transform/resource/after-ecj/GetterLazyGenerics.java @@ -8,37 +8,37 @@ class GetterLazyGenerics { return null; } public @java.lang.SuppressWarnings({"all", "unchecked"}) E getField() { - java.lang.Object value = this.field.get(); - if ((value == null)) + java.lang.Object $value = this.field.get(); + if (($value == null)) { synchronized (this.field) { - value = this.field.get(); - if ((value == null)) + $value = this.field.get(); + if (($value == null)) { final E actualValue = getAny(); - value = ((actualValue == null) ? this.field : actualValue); - this.field.set(value); + $value = ((actualValue == null) ? this.field : actualValue); + this.field.set($value); } } } - return (E) ((value == this.field) ? null : value); + return (E) (($value == this.field) ? null : $value); } public @java.lang.SuppressWarnings({"all", "unchecked"}) long getField2() { - java.lang.Object value = this.field2.get(); - if ((value == null)) + java.lang.Object $value = this.field2.get(); + if (($value == null)) { synchronized (this.field2) { - value = this.field2.get(); - if ((value == null)) + $value = this.field2.get(); + if (($value == null)) { final long actualValue = System.currentTimeMillis(); - value = actualValue; - this.field2.set(value); + $value = actualValue; + this.field2.set($value); } } } - return (java.lang.Long) value; + return (java.lang.Long) $value; } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java b/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java index ab8bc599..dadd8e71 100644 --- a/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java +++ b/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java @@ -7,21 +7,21 @@ public class GetterLazyInAnonymousClass { super(); } public @java.lang.SuppressWarnings({"all", "unchecked"}) String getString() { - java.lang.Object value = this.string.get(); - if ((value == null)) + java.lang.Object $value = this.string.get(); + if (($value == null)) { synchronized (this.string) { - value = this.string.get(); - if ((value == null)) + $value = this.string.get(); + if (($value == null)) { final String actualValue = "test"; - value = ((actualValue == null) ? this.string : actualValue); - this.string.set(value); + $value = ((actualValue == null) ? this.string : actualValue); + this.string.set($value); } } } - return (String) ((value == this.string) ? null : value); + return (String) (($value == this.string) ? null : $value); } } x() { diff --git a/test/transform/resource/after-ecj/GetterLazyNative.java b/test/transform/resource/after-ecj/GetterLazyNative.java index 7808068e..c2769c51 100644 --- a/test/transform/resource/after-ecj/GetterLazyNative.java +++ b/test/transform/resource/after-ecj/GetterLazyNative.java @@ -12,156 +12,156 @@ class GetterLazyNative { super(); } public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isBooleanField() { - java.lang.Object value = this.booleanField.get(); - if ((value == null)) + java.lang.Object $value = this.booleanField.get(); + if (($value == null)) { synchronized (this.booleanField) { - value = this.booleanField.get(); - if ((value == null)) + $value = this.booleanField.get(); + if (($value == null)) { final boolean actualValue = true; - value = actualValue; - this.booleanField.set(value); + $value = actualValue; + this.booleanField.set($value); } } } - return (java.lang.Boolean) value; + return (java.lang.Boolean) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) byte getByteField() { - java.lang.Object value = this.byteField.get(); - if ((value == null)) + java.lang.Object $value = this.byteField.get(); + if (($value == null)) { synchronized (this.byteField) { - value = this.byteField.get(); - if ((value == null)) + $value = this.byteField.get(); + if (($value == null)) { final byte actualValue = 1; - value = actualValue; - this.byteField.set(value); + $value = actualValue; + this.byteField.set($value); } } } - return (java.lang.Byte) value; + return (java.lang.Byte) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) short getShortField() { - java.lang.Object value = this.shortField.get(); - if ((value == null)) + java.lang.Object $value = this.shortField.get(); + if (($value == null)) { synchronized (this.shortField) { - value = this.shortField.get(); - if ((value == null)) + $value = this.shortField.get(); + if (($value == null)) { final short actualValue = 1; - value = actualValue; - this.shortField.set(value); + $value = actualValue; + this.shortField.set($value); } } } - return (java.lang.Short) value; + return (java.lang.Short) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) int getIntField() { - java.lang.Object value = this.intField.get(); - if ((value == null)) + java.lang.Object $value = this.intField.get(); + if (($value == null)) { synchronized (this.intField) { - value = this.intField.get(); - if ((value == null)) + $value = this.intField.get(); + if (($value == null)) { final int actualValue = 1; - value = actualValue; - this.intField.set(value); + $value = actualValue; + this.intField.set($value); } } } - return (java.lang.Integer) value; + return (java.lang.Integer) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) long getLongField() { - java.lang.Object value = this.longField.get(); - if ((value == null)) + java.lang.Object $value = this.longField.get(); + if (($value == null)) { synchronized (this.longField) { - value = this.longField.get(); - if ((value == null)) + $value = this.longField.get(); + if (($value == null)) { final long actualValue = 1; - value = actualValue; - this.longField.set(value); + $value = actualValue; + this.longField.set($value); } } } - return (java.lang.Long) value; + return (java.lang.Long) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) float getFloatField() { - java.lang.Object value = this.floatField.get(); - if ((value == null)) + java.lang.Object $value = this.floatField.get(); + if (($value == null)) { synchronized (this.floatField) { - value = this.floatField.get(); - if ((value == null)) + $value = this.floatField.get(); + if (($value == null)) { final float actualValue = 1.0f; - value = actualValue; - this.floatField.set(value); + $value = actualValue; + this.floatField.set($value); } } } - return (java.lang.Float) value; + return (java.lang.Float) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) double getDoubleField() { - java.lang.Object value = this.doubleField.get(); - if ((value == null)) + java.lang.Object $value = this.doubleField.get(); + if (($value == null)) { synchronized (this.doubleField) { - value = this.doubleField.get(); - if ((value == null)) + $value = this.doubleField.get(); + if (($value == null)) { final double actualValue = 1.0; - value = actualValue; - this.doubleField.set(value); + $value = actualValue; + this.doubleField.set($value); } } } - return (java.lang.Double) value; + return (java.lang.Double) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) char getCharField() { - java.lang.Object value = this.charField.get(); - if ((value == null)) + java.lang.Object $value = this.charField.get(); + if (($value == null)) { synchronized (this.charField) { - value = this.charField.get(); - if ((value == null)) + $value = this.charField.get(); + if (($value == null)) { final char actualValue = '1'; - value = actualValue; - this.charField.set(value); + $value = actualValue; + this.charField.set($value); } } } - return (java.lang.Character) value; + return (java.lang.Character) $value; } public @java.lang.SuppressWarnings({"all", "unchecked"}) int[] getIntArrayField() { - java.lang.Object value = this.intArrayField.get(); - if ((value == null)) + java.lang.Object $value = this.intArrayField.get(); + if (($value == null)) { synchronized (this.intArrayField) { - value = this.intArrayField.get(); - if ((value == null)) + $value = this.intArrayField.get(); + if (($value == null)) { final int[] actualValue = new int[]{1}; - value = ((actualValue == null) ? this.intArrayField : actualValue); - this.intArrayField.set(value); + $value = ((actualValue == null) ? this.intArrayField : actualValue); + this.intArrayField.set($value); } } } - return (int[]) ((value == this.intArrayField) ? null : value); + return (int[]) (($value == this.intArrayField) ? null : $value); } } diff --git a/test/transform/resource/after-ecj/GetterLazyTransient.java b/test/transform/resource/after-ecj/GetterLazyTransient.java index 7e5f4a41..b97fe533 100644 --- a/test/transform/resource/after-ecj/GetterLazyTransient.java +++ b/test/transform/resource/after-ecj/GetterLazyTransient.java @@ -6,21 +6,21 @@ class GetterLazyTransient { super(); } public @java.lang.SuppressWarnings({"all", "unchecked"}) int getNonTransientField() { - java.lang.Object value = this.nonTransientField.get(); - if ((value == null)) + java.lang.Object $value = this.nonTransientField.get(); + if (($value == null)) { synchronized (this.nonTransientField) { - value = this.nonTransientField.get(); - if ((value == null)) + $value = this.nonTransientField.get(); + if (($value == null)) { final int actualValue = 1; - value = actualValue; - this.nonTransientField.set(value); + $value = actualValue; + this.nonTransientField.set($value); } } } - return (java.lang.Integer) value; + return (java.lang.Integer) $value; } public @java.lang.SuppressWarnings("all") int getNonLazyTransientField() { return this.nonLazyTransientField; diff --git a/test/transform/resource/after-ecj/SkipSuppressWarnings.java b/test/transform/resource/after-ecj/SkipSuppressWarnings.java index 53032519..76b79fe2 100644 --- a/test/transform/resource/after-ecj/SkipSuppressWarnings.java +++ b/test/transform/resource/after-ecj/SkipSuppressWarnings.java @@ -8,20 +8,20 @@ class SkipSuppressWarnings { return this.field; } public @java.lang.SuppressWarnings({"unchecked"}) String getField2() { - java.lang.Object value = this.field2.get(); - if ((value == null)) + java.lang.Object $value = this.field2.get(); + if (($value == null)) { synchronized (this.field2) { - value = this.field2.get(); - if ((value == null)) + $value = this.field2.get(); + if (($value == null)) { final String actualValue = ""; - value = ((actualValue == null) ? this.field2 : actualValue); - this.field2.set(value); + $value = ((actualValue == null) ? this.field2 : actualValue); + this.field2.set($value); } } } - return (String) ((value == this.field2) ? null : value); + return (String) (($value == this.field2) ? null : $value); } } \ No newline at end of file From e4824cbe1405fd665f289f7178d6149a8fcdd7b5 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 3 Mar 2024 12:18:53 +0100 Subject: [PATCH 56/65] Fix Javadoc in Eclipse --- .../lombok/eclipse/agent/PatchJavadoc.java | 7 +-- .../lombok/launch/PatchFixesHider.java | 11 ---- .../javadoc/getterSetter/Javadoc.java | 25 +++++++++ .../src/lombok/eclipse/EclipseTests.java | 3 +- .../src/lombok/eclipse/misc/JavadocTest.java | 54 +++++++++++++++++++ 5 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 test/eclipse/resource/javadoc/getterSetter/Javadoc.java create mode 100644 test/eclipse/src/lombok/eclipse/misc/JavadocTest.java diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index f270e19f..38b69bf7 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2021 The Project Lombok Authors. + * Copyright (C) 2020-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 @@ -24,20 +24,15 @@ package lombok.eclipse.agent; import static lombok.eclipse.EcjAugments.CompilationUnit_javadoc; import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.core.CompilationUnit; import org.eclipse.jdt.internal.core.SourceMethod; import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2; -import lombok.eclipse.handlers.EclipseHandlerUtil; import lombok.permit.Permit; public class PatchJavadoc { diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 3bdf7974..74bb0b8a 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -432,26 +432,15 @@ final class PatchFixesHider { /** Contains patch code to support Javadoc for generated methods */ public static final class Javadoc { private static final Method GET_HTML; - private static final Method PRINT_METHOD_OLD; - private static final Method PRINT_METHOD_NEW; static { Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc"); GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class); - PRINT_METHOD_NEW = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuilder.class, TypeDeclaration.class); - PRINT_METHOD_OLD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class); } public static String getHTMLContentFromSource(String original, IJavaElement member) { return (String) Util.invokeMethod(GET_HTML, original, member); } - - public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuilder output, TypeDeclaration type) { - return (StringBuilder) Util.invokeMethod(PRINT_METHOD_NEW, methodDeclaration, tab, output, type); - } - public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) { - return (StringBuffer) Util.invokeMethod(PRINT_METHOD_OLD, methodDeclaration, tab, output, type); - } } /** diff --git a/test/eclipse/resource/javadoc/getterSetter/Javadoc.java b/test/eclipse/resource/javadoc/getterSetter/Javadoc.java new file mode 100644 index 00000000..9f07e9e0 --- /dev/null +++ b/test/eclipse/resource/javadoc/getterSetter/Javadoc.java @@ -0,0 +1,25 @@ +package pkg; + +import lombok.Getter; +import lombok.Setter; + +public class Javadoc { + /** + * Some text + * + * **SETTER** + * Setter section + * @param fieldName Hello, World3 + * **GETTER** + * Getter section + * @return Sky is blue3 + */ + @Getter + @Setter + private int field; + + public void usage() { + getField(); + setField(0); + } +} \ 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 04f78f0f..e09313dd 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseTests.java +++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java @@ -28,13 +28,14 @@ import org.junit.runners.Suite.SuiteClasses; import lombok.eclipse.cleanup.CleanupTest; import lombok.eclipse.compile.NoErrorsTest; import lombok.eclipse.edit.SelectTest; +import lombok.eclipse.misc.JavadocTest; import lombok.eclipse.refactoring.ExtractInterfaceTest; import lombok.eclipse.refactoring.InlineTest; import lombok.eclipse.refactoring.RenameTest; import lombok.eclipse.references.FindReferencesTest; @RunWith(Suite.class) -@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class}) +@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class, JavadocTest.class}) public class EclipseTests { } diff --git a/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java new file mode 100644 index 00000000..bbd73125 --- /dev/null +++ b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java @@ -0,0 +1,54 @@ +/* + * 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.junit.Assert.assertEquals; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2; +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 JavadocTest { + + @Rule + public SetupSingleFileTest setup = new SetupSingleFileTest(); + + @Test + public void getterSetter() throws Exception { + ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("Javadoc.java"); + + IJavaElement getterInvocation = cu.codeSelect(306, 0)[0]; + String getterHtmlContent = JavadocContentAccess2.getHTMLContent(getterInvocation, true); + assertEquals("Getter section
Returns:
Sky is blue3
", getterHtmlContent); + + IJavaElement setterInvocation = cu.codeSelect(320, 0)[0]; + String setterHtmlContent = JavadocContentAccess2.getHTMLContent(setterInvocation, true); + assertEquals("Setter section
Parameters:
fieldName Hello, World3
field
", setterHtmlContent); + } +} From 98cdf67ed6846580e8e4e77391fd48f3293603f6 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sat, 9 Mar 2024 11:39:23 +0100 Subject: [PATCH 57/65] Javadoc support for eclipse 2024-03 --- .../lombok/eclipse/agent/EclipsePatcher.java | 8 ++++ .../lombok/eclipse/agent/PatchJavadoc.java | 42 ++++++++++++------- .../lombok/launch/PatchFixesHider.java | 8 +++- .../src/lombok/eclipse/misc/JavadocTest.java | 13 ++++-- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index c176f515..12060ffb 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -967,6 +967,14 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { } private static void patchJavadoc(ScriptManager sm) { + // Moved to new package and changed to instance method in 2024-03 + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall() + .target(new MethodTarget("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IJavaElement", "boolean")) + .methodToWrap(new Hook("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess", "getHTMLContentFromSource", "java.lang.String", "org.eclipse.jdt.core.IJavaElement")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "getHTMLContentFromSource", "java.lang.String", "java.lang.String", "java.lang.Object", "org.eclipse.jdt.core.IJavaElement")) + .requestExtra(StackRequest.THIS, StackRequest.PARAM1) + .build()); + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall() .target(new MethodTarget("org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IJavaElement", "boolean")) .methodToWrap(new Hook("org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2", "getHTMLContentFromSource", "java.lang.String", "org.eclipse.jdt.core.IJavaElement")) diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java index 38b69bf7..caa94e2f 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java @@ -37,7 +37,7 @@ import lombok.permit.Permit; public class PatchJavadoc { - public static String getHTMLContentFromSource(String original, Object member) { + public static String getHTMLContentFromSource(Object instance, String original, Object member) { if (original != null) { return original; } @@ -54,7 +54,7 @@ public class PatchJavadoc { String rawJavadoc = docs.get(signature); if (rawJavadoc == null) return null; - return Reflection.javadoc2HTML((IMember) member, (IJavaElement) member, rawJavadoc); + return Reflection.javadoc2HTML(instance, (IMember) member, (IJavaElement) member, rawJavadoc); } } @@ -85,9 +85,10 @@ public class PatchJavadoc { private static class Reflection { private static final Method javadoc2HTML; private static final Method oldJavadoc2HTML; + private static final Method reallyOldJavadoc2HTML; private static final Method lsJavadoc2HTML; static { - Method a = null, b = null, c = null; + Method a = null, b = null, c = null, d = null; try { a = Permit.getMethod(JavadocContentAccess2.class, "javadoc2HTML", IMember.class, IJavaElement.class, String.class); @@ -98,30 +99,41 @@ public class PatchJavadoc { try { c = Permit.getMethod(Class.forName("org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2"), "javadoc2HTML", IMember.class, IJavaElement.class, String.class); } catch (Throwable t) {} + try { + d = Permit.getMethod(Class.forName("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess"), "javadoc2HTML", IMember.class, IJavaElement.class, String.class); + } catch (Throwable t) {} - javadoc2HTML = a; - oldJavadoc2HTML = b; + oldJavadoc2HTML = a; + reallyOldJavadoc2HTML = b; lsJavadoc2HTML = c; + javadoc2HTML = d; } - private static String javadoc2HTML(IMember member, IJavaElement element, String rawJavadoc) { + private static String javadoc2HTML(Object instance, IMember member, IJavaElement element, String rawJavadoc) { if (javadoc2HTML != null) { try { - return (String) javadoc2HTML.invoke(null, member, element, rawJavadoc); - } catch (Throwable t) { - return null; - } - } - if (lsJavadoc2HTML != null) { - try { - return (String) lsJavadoc2HTML.invoke(null, member, element, rawJavadoc); + return (String) javadoc2HTML.invoke(instance, member, element, rawJavadoc); } catch (Throwable t) { return null; } } if (oldJavadoc2HTML != null) { try { - return (String) oldJavadoc2HTML.invoke(null, member, rawJavadoc); + return (String) oldJavadoc2HTML.invoke(instance, member, element, rawJavadoc); + } catch (Throwable t) { + return null; + } + } + if (lsJavadoc2HTML != null) { + try { + return (String) lsJavadoc2HTML.invoke(instance, member, element, rawJavadoc); + } catch (Throwable t) { + return null; + } + } + if (reallyOldJavadoc2HTML != null) { + try { + return (String) reallyOldJavadoc2HTML.invoke(instance, member, rawJavadoc); } catch (Throwable t) { return null; } diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 74bb0b8a..84a0cf3d 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -435,11 +435,15 @@ final class PatchFixesHider { static { Class shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc"); - GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class); + GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", Object.class, String.class, Object.class); } public static String getHTMLContentFromSource(String original, IJavaElement member) { - return (String) Util.invokeMethod(GET_HTML, original, member); + return (String) Util.invokeMethod(GET_HTML, null, original, member); + } + + public static String getHTMLContentFromSource(String original, Object instance, IJavaElement member) { + return (String) Util.invokeMethod(GET_HTML, instance, original, member); } } diff --git a/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java index bbd73125..fd7a5daa 100644 --- a/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java +++ b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java @@ -21,11 +21,12 @@ */ package lombok.eclipse.misc; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2; +import org.hamcrest.CoreMatchers; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,10 +46,16 @@ public class JavadocTest { IJavaElement getterInvocation = cu.codeSelect(306, 0)[0]; String getterHtmlContent = JavadocContentAccess2.getHTMLContent(getterInvocation, true); - assertEquals("Getter section
Returns:
Sky is blue3
", getterHtmlContent); + assertThat(getterHtmlContent, CoreMatchers.containsString("Getter section")); + assertThat(getterHtmlContent, CoreMatchers.containsString("Returns:")); + assertThat(getterHtmlContent, CoreMatchers.containsString("Sky is blue3")); IJavaElement setterInvocation = cu.codeSelect(320, 0)[0]; String setterHtmlContent = JavadocContentAccess2.getHTMLContent(setterInvocation, true); - assertEquals("Setter section
Parameters:
fieldName Hello, World3
field
", setterHtmlContent); + assertThat(setterHtmlContent, CoreMatchers.containsString("Setter section")); + assertThat(setterHtmlContent, CoreMatchers.containsString("Parameters:")); + assertThat(setterHtmlContent, CoreMatchers.containsString("fieldName")); + assertThat(setterHtmlContent, CoreMatchers.containsString("Hello, World3")); + assertThat(setterHtmlContent, CoreMatchers.containsString("field")); } } From 3b20b70363fe85f354934fcfb47fdcfd0701a31e Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 12 Mar 2024 22:12:22 +0100 Subject: [PATCH 58/65] 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 12060ffb..e3a52ba1 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -771,6 +771,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .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 d7b17598..fee6db43 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 class PatchDelegate { 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 84a0cf3d..7ba663cc 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -277,11 +277,16 @@ final class PatchFixesHider { 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 @@ final class PatchFixesHider { 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 00000000..4c1700e9 --- /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 e09313dd..66f5d9fa 100644 --- a/test/eclipse/src/lombok/eclipse/EclipseTests.java +++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java @@ -28,6 +28,7 @@ import org.junit.runners.Suite.SuiteClasses; 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.refactoring.RenameTest; 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 00000000..899dc9f9 --- /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(); + } + } +} From 521be03be45887ea738e005b5f317e04ca6196d2 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 12 Mar 2024 23:24:38 +0100 Subject: [PATCH 59/65] Remove unused string literal code This code was never used because StringLiteralConcatenation and ExtendedStringLiteral extend StringLiterals and get handled a few lines above. We might need to add it back and fix it if we want to copy annotations like @Annotation("a" + "b") without transforming them to @Annotation("ab") --- .../eclipse/handlers/EclipseHandlerUtil.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 1e4c4f23..ef7a7c3a 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -22,8 +22,8 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.*; -import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.EcjAugments.*; +import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.EclipseReflectiveMembers.*; import java.lang.reflect.Array; @@ -60,7 +60,6 @@ import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral; import org.eclipse.jdt.internal.compiler.ast.EqualExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral; import org.eclipse.jdt.internal.compiler.ast.FalseLiteral; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; @@ -86,7 +85,6 @@ import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.StringLiteral; -import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; import org.eclipse.jdt.internal.compiler.ast.TrueLiteral; @@ -123,6 +121,7 @@ import lombok.core.configuration.TypeName; import lombok.core.debug.ProblemReporter; import lombok.core.handlers.HandlerUtil; import lombok.core.handlers.HandlerUtil.FieldAccess; +import lombok.core.handlers.HandlerUtil.JavadocTag; import lombok.eclipse.EcjAugments; import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAST; @@ -416,20 +415,6 @@ public class EclipseHandlerUtil { if (in instanceof LongLiteral) return LongLiteral.buildLongLiteral(((Literal) in).source(), s, e); if (in instanceof StringLiteral) return new StringLiteral(((Literal) in).source(), s, e, reflectInt(STRING_LITERAL__LINE_NUMBER, in) + 1); - if (in instanceof ExtendedStringLiteral) { - StringLiteral str = new StringLiteral(((Literal) in).source(), s, e, reflectInt(STRING_LITERAL__LINE_NUMBER, in) + 1); - StringLiteral empty = new StringLiteral(new char[0], s, e, reflectInt(STRING_LITERAL__LINE_NUMBER, in) + 1); - return new ExtendedStringLiteral(str, empty); - } - if (in instanceof StringLiteralConcatenation) { - Expression[] literals = ((StringLiteralConcatenation) in).literals; - // 0 and 1 len shouldn't happen. - if (literals.length == 0) return new StringLiteral(new char[0], s, e, 0); - if (literals.length == 1) return copyAnnotationMemberValue0(literals[0]); - StringLiteralConcatenation c = new StringLiteralConcatenation((StringLiteral) literals[0], (StringLiteral) literals[1]); - for (int i = 2; i < literals.length; i++) c = c.extendsWith((StringLiteral) literals[i]); - return c; - } // enums and field accesses (as long as those are references to compile time constant literals that's also acceptable) From 1b713add959430ee22145050a638f01102d158c5 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Thu, 14 Mar 2024 21:24:07 +0100 Subject: [PATCH 60/65] Add eclipse 2024-03 as test target --- .github/workflows/ant.yml | 2 ++ buildScripts/ivy.xml | 14 ++++++++++++++ buildScripts/setup.ant.xml | 4 ++++ buildScripts/tests.ant.xml | 9 +++++++++ 4 files changed, 29 insertions(+) diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml index 2022b3a6..278f9752 100644 --- a/.github/workflows/ant.yml +++ b/.github/workflows/ant.yml @@ -106,11 +106,13 @@ jobs: - eclipse-202212 - eclipse-202309 - eclipse-202312 + - eclipse-202403 - eclipse-I-build - eclipse-oxygen-full - eclipse-2022-03-full - eclipse-2023-09-full - eclipse-2023-12-full + - eclipse-2024-03-full - eclipse-I-build-full - ecj11 - ecj14 diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml index c981c5fe..c3687cb8 100644 --- a/buildScripts/ivy.xml +++ b/buildScripts/ivy.xml @@ -33,6 +33,7 @@ + @@ -146,6 +147,19 @@ + + + + + + + + + + + + + diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index 4f73f956..2a25a9ba 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -172,6 +172,10 @@ This buildfile is part of projectlombok.org. It sets up the build itself. + + + + diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml index ade6fbff..8f7023db 100644 --- a/buildScripts/tests.ant.xml +++ b/buildScripts/tests.ant.xml @@ -223,6 +223,11 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn + + + + + @@ -295,6 +300,10 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn + + + + From 5719fde58e1faf04d436e85c86ae50acf8ede272 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Mon, 18 Mar 2024 19:21:29 +0100 Subject: [PATCH 61/65] Update changelog in preparation for the upcoming release --- doc/changelog.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index a3b3a48a..a8375ac7 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,12 +2,18 @@ Lombok Changelog ---------------- ### v1.18.31 "Edgy Guinea Pig" +* PLATFORM: Initial JDK22 support added. +* PLAFTORM Added support for Eclipse 2024-03. [Issue #3620](https://github.com/projectlombok/lombok/issues/3620). * PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564). * FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506). * NECROMANCY: Inlining a generated getter in eclipse would result in eclipse incorrectly replacing calls with `@Getter` instead of the actual field's name. [Issue #562](https://github.com/projectlombok/lombok/issues/562). This issue is almost old enough to drink. Points for dedication go to Rawi for fixing this one. +* BUGFIX: When `@SuperBuilder` was used on a type with an annotated generic type, it would error `wrong number of type arguments`. [Issue #3592](https://github.com/projectlombok/lombok/issues/3592). +* BUGFIX: It was possible to create an infinite build loop using `@ExtensionMethod`. [Issue #3225](https://github.com/projectlombok/lombok/issues/3225). +* BUGFIX: Using `@Getter(lazy=true)` would fail if the expression contained a variable called `value`. [Issue #2917](https://github.com/projectlombok/lombok/issues/2917). * BUGFIX: Many lombok features wouldn't work properly on records contained within an outer type unless you explicitly marked it `static`. [Issue #3497](https://github.com/projectlombok/lombok/issues/3497) [Issue #3559](https://github.com/projectlombok/lombok/issues/3559). * BUGFIX: Eclipse projects using the `com.pro-crafting.tools:jasperreports-plugin` will now compile. * BUGFIX: `@FieldNameConstants` now works when generated fields are involved. [Issue #3529](https://github.com/projectlombok/lombok/issues/3529). +* IMPROBABLE BREAKING CHANGE: For JSpecify, the package name changed from `org.jspecify.nullness` to `org.jspecify.annotations`, which might lead to a different null analysis. [Issue #3608](https://github.com/projectlombok/lombok/pull/3608). ### v1.18.30 (September 20th, 2023) * PLATFORM: Initial JDK21 support added. [Issue #3393](https://github.com/projectlombok/lombok/issues/3393). From 2618848385de2ec4b79677e01eb8045714de1110 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 20 Mar 2024 01:09:17 +0100 Subject: [PATCH 62/65] [release] pre-release version bump --- doc/changelog.markdown | 2 +- src/core/lombok/core/Version.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index a8375ac7..08111c00 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,7 +1,7 @@ Lombok Changelog ---------------- -### v1.18.31 "Edgy Guinea Pig" +### v1.18.32 (March 20th, 2024) * PLATFORM: Initial JDK22 support added. * PLAFTORM Added support for Eclipse 2024-03. [Issue #3620](https://github.com/projectlombok/lombok/issues/3620). * PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564). diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index c8471879..fa8c6c25 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2023 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -30,9 +30,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.18.31"; - private static final String RELEASE_NAME = "Edgy Guinea Pig"; -// private static final String RELEASE_NAME = "Envious Ferret"; + private static final String VERSION = "1.18.32"; +// private static final String RELEASE_NAME = "Edgy Guinea Pig"; + private static final String RELEASE_NAME = "Envious Ferret"; // Named version history: // Angry Butterfly From 0023c598c7699a74b2c8893be104568997c6bf6e Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 20 Mar 2024 01:11:52 +0100 Subject: [PATCH 63/65] [docs] Locked.html had a wrong import --- website/templates/features/Locked.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/features/Locked.html b/website/templates/features/Locked.html index 105bf6dc..fa041975 100644 --- a/website/templates/features/Locked.html +++ b/website/templates/features/Locked.html @@ -1,4 +1,4 @@ -<#import "../_features.html" as f> +<#import "_features.html" as f> <@f.scaffold title="@Locked" logline="Pop it and lock it! ReentrantLock, now with less hassle."> <@f.history> From d2a18ebf757ba3bdc550a00114fb64f99adb2baa Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 20 Mar 2024 01:13:12 +0100 Subject: [PATCH 64/65] [docs] Locked example needed its usage examples moved --- website/usageExamples/{experimental => }/LockedExample_post.jpage | 0 website/usageExamples/{experimental => }/LockedExample_pre.jpage | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename website/usageExamples/{experimental => }/LockedExample_post.jpage (100%) rename website/usageExamples/{experimental => }/LockedExample_pre.jpage (100%) diff --git a/website/usageExamples/experimental/LockedExample_post.jpage b/website/usageExamples/LockedExample_post.jpage similarity index 100% rename from website/usageExamples/experimental/LockedExample_post.jpage rename to website/usageExamples/LockedExample_post.jpage diff --git a/website/usageExamples/experimental/LockedExample_pre.jpage b/website/usageExamples/LockedExample_pre.jpage similarity index 100% rename from website/usageExamples/experimental/LockedExample_pre.jpage rename to website/usageExamples/LockedExample_pre.jpage From 9dc7e7f0cf55554c90ae59f00e73d810d4cce22b Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Wed, 20 Mar 2024 01:21:03 +0100 Subject: [PATCH 65/65] [release] post-release version bump --- doc/changelog.markdown | 3 +++ src/core/lombok/core/Version.java | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 08111c00..7303de17 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,6 +1,9 @@ Lombok Changelog ---------------- +### v1.18.33 "Edgy Guinea Pig" +* We recently released v1.18.32; there is no edge release since then. + ### v1.18.32 (March 20th, 2024) * PLATFORM: Initial JDK22 support added. * PLAFTORM Added support for Eclipse 2024-03. [Issue #3620](https://github.com/projectlombok/lombok/issues/3620). diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index fa8c6c25..7caf52da 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,9 +30,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.18.32"; -// private static final String RELEASE_NAME = "Edgy Guinea Pig"; - private static final String RELEASE_NAME = "Envious Ferret"; + private static final String VERSION = "1.18.33"; + private static final String RELEASE_NAME = "Edgy Guinea Pig"; +// private static final String RELEASE_NAME = "Envious Ferret"; // Named version history: // Angry Butterfly