From 9af596e29ecb0375d3474e4de7299cb21ecadbd6 Mon Sep 17 00:00:00 2001
From: tamila-krashtan
Date: Sat, 26 Oct 2024 17:58:00 +0300
Subject: [PATCH 01/47] Fix typo in With.html
---
website/templates/features/With.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/templates/features/With.html b/website/templates/features/With.html
index 867c17eb..f4809d26 100644
--- a/website/templates/features/With.html
+++ b/website/templates/features/With.html
@@ -27,7 +27,7 @@
<@f.snippets name="With" />
<@f.confKeys>
- <>
+
lombok.accessors.prefix += a field prefix (default: empty list)
This is a list property; entries can be added with the += operator. Inherited prefixes from parent config files can be removed with the -= operator. Lombok will strip any matching field prefix from the name of a field in order to determine the name of the getter/setter to generate. For example, if m is one of the prefixes listed in this setting, then a field named mFoobar will result in a getter named getFoobar(), not getMFoobar(). An explicitly configured prefix parameter of an @Accessors annotation takes precedence over this setting.
From 033870592900e47d9855d190924d0addecddad61 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 15 Nov 2024 01:20:14 +0100
Subject: [PATCH 02/47] Revert "[fixes #3116] Add multi round support for
mapstruct":
This reverts commit 04c9755b39617a0e222a8e88ef44677b34044ab2.
The nature of the fix is to simply scan the TypeMirror for 'lombok shenanigans'; if it finds them, the type is not complete; if there are none, the type is.
This fundamentally does not work - lombok shenanigans may remain even if lombok is done (`@lombok.NonNull` for example), and lombok shenanigans don't just appear as annotations on the type; they can appear in many forms: Annotations on local var decls, or even method calls to `Lombok.safeDeNull` or whatnot. safeDenull is made up, but we might add it someday. `@Getter` on a field isn't though, and suffers from the same problem.
---
AUTHORS | 1 -
.../lombok/mapstruct/NotifierHider.java | 38 ++++++++++---------
.../lombok/launch/AnnotationProcessor.java | 5 +++
3 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 67e80060..a8c9bcc4 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,7 +1,6 @@
Lombok contributors in alphabetical order:
Adam Juraszek
-Aleksandar Kanchev <136312841+kanchev1@users.noreply.github.com>
Aleksandr Zhelezniak
Amine Touzani
Andre Brait
diff --git a/src/bindings/mapstruct/lombok/mapstruct/NotifierHider.java b/src/bindings/mapstruct/lombok/mapstruct/NotifierHider.java
index 834b5bf2..222e9c0b 100644
--- a/src/bindings/mapstruct/lombok/mapstruct/NotifierHider.java
+++ b/src/bindings/mapstruct/lombok/mapstruct/NotifierHider.java
@@ -1,29 +1,33 @@
package lombok.mapstruct;
+import java.lang.reflect.Field;
+
+import javax.lang.model.type.TypeMirror;
+
import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.type.TypeMirror;
-import java.util.List;
-
-/**
- * Report to MapStruct that a type is completed when there aren't any Lombok annotations left on it. Lombok annotations
- * are removed whenever a class is processed. This way, annotations which require multiple rounds to process are also
- * correctly handled, and MapStruct processing will be delayed until Lombok completely finishes processing required types.
- */
class NotifierHider {
public static class AstModificationNotifier implements AstModifyingAnnotationProcessor {
- @Override
- public boolean isTypeComplete(TypeMirror typeMirror) {
+ private static Field lombokInvoked;
+
+ @Override public boolean isTypeComplete(TypeMirror type) {
if (System.getProperty("lombok.disable") != null) return true;
- List extends AnnotationMirror> annotationMirrors = typeMirror.getAnnotationMirrors();
- if (annotationMirrors == null || annotationMirrors.isEmpty()) return true;
-
- for (AnnotationMirror annotationMirror : annotationMirrors) {
- String annotationName = String.valueOf(annotationMirror);
- if (annotationName.startsWith("@lombok.")) return false;
+ return isLombokInvoked();
+ }
+
+ private static boolean isLombokInvoked() {
+ if (lombokInvoked != null) {
+ try {
+ return lombokInvoked.getBoolean(null);
+ } catch (Exception e) {}
+ return true;
}
+ try {
+ Class> data = Class.forName("lombok.launch.AnnotationProcessorHider$AstModificationNotifierData");
+ lombokInvoked = data.getField("lombokInvoked");
+ return lombokInvoked.getBoolean(null);
+ } catch (Exception e) {}
return true;
}
}
diff --git a/src/launch/lombok/launch/AnnotationProcessor.java b/src/launch/lombok/launch/AnnotationProcessor.java
index 28a28d72..456a8cef 100644
--- a/src/launch/lombok/launch/AnnotationProcessor.java
+++ b/src/launch/lombok/launch/AnnotationProcessor.java
@@ -39,6 +39,10 @@ import sun.misc.Unsafe;
class AnnotationProcessorHider {
+ public static class AstModificationNotifierData {
+ public volatile static boolean lombokInvoked = false;
+ }
+
public static class AnnotationProcessor extends AbstractProcessor {
private final AbstractProcessor instance = createWrappedInstance();
@@ -56,6 +60,7 @@ class AnnotationProcessorHider {
@Override public void init(ProcessingEnvironment processingEnv) {
disableJava9SillyWarning();
+ AstModificationNotifierData.lombokInvoked = true;
instance.init(processingEnv);
super.init(processingEnv);
}
From 91d79ff9fbef24494039a9f37498a4fd4386459e Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 15 Nov 2024 01:37:45 +0100
Subject: [PATCH 03/47] [release] pre-release version bump
---
doc/changelog.markdown | 2 +-
src/core/lombok/core/Version.java | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 96894b96..b3a8b585 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,7 +1,7 @@
Lombok Changelog
----------------
-### v1.18.35 "Edgy Guinea Pig"
+### v1.18.36 (November 15th, 2024)
* PLATFORM: JDK23 support added.
* BUGFIX: Eclipse projects using the `com.pro-crafting.tools:jasperreports-maven-plugin` will now compile.
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index 0e18719b..582741fd 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.35";
- private static final String RELEASE_NAME = "Edgy Guinea Pig";
-// private static final String RELEASE_NAME = "Envious Ferret";
+ private static final String VERSION = "1.18.36";
+// private static final String RELEASE_NAME = "Edgy Guinea Pig";
+ private static final String RELEASE_NAME = "Envious Ferret";
// Named version history:
// Angry Butterfly
From 8ae385ce1487f3be498dabc08f9cc2153e8fd89e Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 15 Nov 2024 01:48:15 +0100
Subject: [PATCH 04/47] [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 b3a8b585..469a638c 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,6 +1,9 @@
Lombok Changelog
----------------
+### v1.18.37 "Edgy Guinea Pig"
+* We recently released v1.18.36; there is no edge release since then.
+
### v1.18.36 (November 15th, 2024)
* PLATFORM: JDK23 support added.
* BUGFIX: Eclipse projects using the `com.pro-crafting.tools:jasperreports-maven-plugin` will now compile.
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index 582741fd..789bbf5e 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.36";
-// private static final String RELEASE_NAME = "Edgy Guinea Pig";
- private static final String RELEASE_NAME = "Envious Ferret";
+ private static final String VERSION = "1.18.37";
+ private static final String RELEASE_NAME = "Edgy Guinea Pig";
+// private static final String RELEASE_NAME = "Envious Ferret";
// Named version history:
// Angry Butterfly
From 8e25adab69e52f61e320a9324af9738ed4a0a816 Mon Sep 17 00:00:00 2001
From: Lukasz Kryger
Date: Fri, 15 Nov 2024 14:40:07 +0100
Subject: [PATCH 05/47] Replace markdown with HTML markup
One of the earlier commits replaced HTML tags with markdown backticks, which are not rendering the code blocks correctly on the website.
---
website/templates/features/Builder.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html
index 05881083..4fd90741 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 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.
+ 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").
@@ -228,7 +228,7 @@ public class JacksonExample {
You can use @Builder for copy constructors: foo.toBuilder().build() makes a shallow clone. Consider suppressing the generating of the
builder method if you just want this functionality, by using: @Builder(toBuilder = true, builderMethodName = "").
- Due to a peculiar way javac processes static imports, trying to do a non-star static import of the static builder() method won't work. Either use a star static import: `import static TypeThatHasABuilder.*;` or don't statically import the builder method.
+ Due to a peculiar way javac processes static imports, trying to do a non-star static import of the static builder() method won't work. Either use a star static import: import static TypeThatHasABuilder.*; or don't statically import the builder method.
If setting the access level to PROTECTED, all methods generated inside the builder class are actually generated as public; the meaning of the
protected keyword is different inside the inner class, and the precise behavior that PROTECTED would indicate (access by any source in the same package is allowed, as well as any subclasses from the outer class, marked with @Builder is not possible, and marking the inner members public is as close as we can get.
From 4f29214445ec6c09dc53796463c3df50e816bff6 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sat, 23 Nov 2024 11:48:25 +0100
Subject: [PATCH 06/47] [fixes #3783] Return generated node for side effect
check
---
.../lombok/eclipse/agent/EclipsePatcher.java | 12 ++++
.../lombok/launch/PatchFixesHider.java | 14 ++++
.../extractvariable/multiple/after/A.java | 15 +++++
.../extractvariable/multiple/before/A.java | 14 ++++
.../extractvariable/single/after/A.java | 13 ++++
.../extractvariable/single/before/A.java | 12 ++++
.../src/lombok/eclipse/EclipseTests.java | 3 +-
.../src/lombok/eclipse/RefactoringUtils.java | 6 +-
.../refactoring/ExtractVariableTest.java | 65 +++++++++++++++++++
9 files changed, 150 insertions(+), 4 deletions(-)
create mode 100644 test/eclipse/resource/extractvariable/multiple/after/A.java
create mode 100644 test/eclipse/resource/extractvariable/multiple/before/A.java
create mode 100644 test/eclipse/resource/extractvariable/single/after/A.java
create mode 100644 test/eclipse/resource/extractvariable/single/before/A.java
create mode 100644 test/eclipse/src/lombok/eclipse/refactoring/ExtractVariableTest.java
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 18d6594a..83330faf 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -96,6 +96,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
patchSyntaxAndOccurrencesHighlighting(sm);
patchSortMembersOperation(sm);
patchExtractInterfaceAndPullUp(sm);
+ patchExtractVariable(sm);
patchAboutDialog(sm);
patchEclipseDebugPatches(sm);
patchJavadoc(sm);
@@ -225,6 +226,17 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.build());
}
+ private static void patchExtractVariable(ScriptManager sm) {
+ /* Fix sourceEnding for generated nodes to avoid null pointer */
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.replaceMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.util.SideEffectChecker", "findFunctionDefinition", "org.eclipse.jdt.core.dom.MethodDeclaration", "org.eclipse.jdt.core.dom.ITypeBinding", "org.eclipse.jdt.core.dom.IMethodBinding"))
+ .methodToReplace(new Hook("org.eclipse.jdt.core.dom.NodeFinder", "perform", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.ISourceRange"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "findGeneratedNode", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.dom.ASTNode", "org.eclipse.jdt.core.ISourceRange", "org.eclipse.jdt.core.dom.IMethodBinding"))
+ .requestExtra(StackRequest.PARAM2)
+ .transplant()
+ .build());
+ }
+
private static void patchInline(ScriptManager sm) {
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.corext.refactoring.code.SourceProvider", "getCodeBlocks", "java.lang.String[]", "org.eclipse.jdt.internal.corext.refactoring.code.CallContext", "org.eclipse.jdt.core.dom.rewrite.ImportRewrite"))
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index 1b005c57..5556771f 100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -41,12 +41,16 @@ import org.eclipse.jdt.core.IAnnotatable;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
@@ -951,6 +955,16 @@ final class PatchFixesHider {
return blocks;
}
}
+
+ public static ASTNode findGeneratedNode(ASTNode root, ISourceRange sourceRange, IMethodBinding methodBinding) {
+ ASTNode result = NodeFinder.perform(root, sourceRange);
+ if (result instanceof MethodDeclaration){
+ return result;
+ }
+
+ CompilationUnit cu = (CompilationUnit) root;
+ return cu.findDeclaringNode(methodBinding.getKey());
+ }
}
public static class FieldInitializer {
diff --git a/test/eclipse/resource/extractvariable/multiple/after/A.java b/test/eclipse/resource/extractvariable/multiple/after/A.java
new file mode 100644
index 00000000..17cf0cdf
--- /dev/null
+++ b/test/eclipse/resource/extractvariable/multiple/after/A.java
@@ -0,0 +1,15 @@
+package pkg;
+
+import java.util.Arrays;
+
+import lombok.Getter;
+
+@Getter
+public class A {
+ private String string;
+
+ public List test() {
+ String temp = getString();
+ return Arrays.asList(temp, temp, temp);
+ }
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/extractvariable/multiple/before/A.java b/test/eclipse/resource/extractvariable/multiple/before/A.java
new file mode 100644
index 00000000..d85d0628
--- /dev/null
+++ b/test/eclipse/resource/extractvariable/multiple/before/A.java
@@ -0,0 +1,14 @@
+package pkg;
+
+import java.util.Arrays;
+
+import lombok.Getter;
+
+@Getter
+public class A {
+ private String string;
+
+ public List test() {
+ return Arrays.asList(getString(), getString(), getString());
+ }
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/extractvariable/single/after/A.java b/test/eclipse/resource/extractvariable/single/after/A.java
new file mode 100644
index 00000000..c11ab11b
--- /dev/null
+++ b/test/eclipse/resource/extractvariable/single/after/A.java
@@ -0,0 +1,13 @@
+package pkg;
+
+import lombok.Getter;
+
+@Getter
+public class A {
+ private String string;
+
+ public String test() {
+ String temp = getString();
+ return temp;
+ }
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/extractvariable/single/before/A.java b/test/eclipse/resource/extractvariable/single/before/A.java
new file mode 100644
index 00000000..1a00bf5a
--- /dev/null
+++ b/test/eclipse/resource/extractvariable/single/before/A.java
@@ -0,0 +1,12 @@
+package pkg;
+
+import lombok.Getter;
+
+@Getter
+public class A {
+ private String string;
+
+ public String test() {
+ return getString();
+ }
+}
\ 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 66f5d9fa..c0306aa6 100644
--- a/test/eclipse/src/lombok/eclipse/EclipseTests.java
+++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java
@@ -31,12 +31,13 @@ import lombok.eclipse.edit.SelectTest;
import lombok.eclipse.misc.DelegateTest;
import lombok.eclipse.misc.JavadocTest;
import lombok.eclipse.refactoring.ExtractInterfaceTest;
+import lombok.eclipse.refactoring.ExtractVariableTest;
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, JavadocTest.class, DelegateTest.class})
+@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class, JavadocTest.class, DelegateTest.class, ExtractVariableTest.class})
public class EclipseTests {
}
diff --git a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
index 2362ff11..de6d7e49 100644
--- a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
+++ b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Project Lombok Authors.
+ * 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
@@ -21,7 +21,7 @@
*/
package lombok.eclipse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@@ -45,7 +45,7 @@ public class RefactoringUtils {
ResourcesPlugin.getWorkspace().run(perform, null);
- assertTrue("Condition failed", change.getConditionCheckingStatus().isOK());
+ assertEquals("Condition failed", "", change.getConditionCheckingStatus().toString());
assertTrue("Perform failed", perform.changeExecuted());
}
}
diff --git a/test/eclipse/src/lombok/eclipse/refactoring/ExtractVariableTest.java b/test/eclipse/src/lombok/eclipse/refactoring/ExtractVariableTest.java
new file mode 100644
index 00000000..50e5b066
--- /dev/null
+++ b/test/eclipse/src/lombok/eclipse/refactoring/ExtractVariableTest.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.eclipse.refactoring;
+
+import static lombok.eclipse.RefactoringUtils.performRefactoring;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.corext.refactoring.code.ExtractTempRefactoring;
+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import lombok.eclipse.EclipseRunner;
+import lombok.eclipse.SetupBeforeAfterTest;
+
+@RunWith(EclipseRunner.class)
+public class ExtractVariableTest {
+
+ @Rule
+ public SetupBeforeAfterTest setup = new SetupBeforeAfterTest();
+
+ @Test
+ public void single() throws Exception {
+ ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("A.java");
+
+ CompilationUnit compilationUnit = new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(cu, true);
+
+ ExtractTempRefactoring extractTempRefactoring = new ExtractTempRefactoring(compilationUnit, 121, 11);
+ extractTempRefactoring.setTempName("temp");
+ performRefactoring(extractTempRefactoring);
+ }
+
+ @Test
+ public void multiple() throws Exception {
+ ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("A.java");
+
+ CompilationUnit compilationUnit = new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(cu, true);
+
+ ExtractTempRefactoring extractTempRefactoring = new ExtractTempRefactoring(compilationUnit, 167, 11);
+ extractTempRefactoring.setTempName("temp");
+ performRefactoring(extractTempRefactoring);
+ }
+}
From 6dc461a13aae607780a3ef3dfd68dda7c8abb1b2 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sat, 23 Nov 2024 13:23:01 +0100
Subject: [PATCH 07/47] [ci] Switch to Ubuntu 24.04 (ships with ant 1.10.14)
---
.github/workflows/ant.yml | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index 26fe5426..a216ebba 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -6,7 +6,7 @@ on:
jobs:
build:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
steps:
- name: Checkout
@@ -38,7 +38,7 @@ jobs:
test-javac:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
needs: build
env:
EA_JDK: 23
@@ -71,15 +71,6 @@ jobs:
website: jdk.java.net
release: ${{ matrix.jdk }}
version: latest
-
- - name: Install Ant
- env:
- ANT_VERSION: 1.10.14
- run: |
- 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@v4
@@ -95,7 +86,7 @@ jobs:
run: ant -noinput test.${{ matrix.goal }}
test-eclipse:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
needs: build
strategy:
matrix:
@@ -164,7 +155,7 @@ jobs:
run: xvfb-run ant -noinput dist test.${{ matrix.version }}
docker-integration-test:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
needs: build
strategy:
matrix:
From 4294ebd301ae18d196474d65083b9c5f9b48b70e Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sun, 24 Nov 2024 20:58:41 +0100
Subject: [PATCH 08/47] [fixes #3605] Remove outer type reference when marking
class as static
The class now implements Serializable to trigger generation of this$0
fields in the inner class. Since Java 18 the compiler only generates the
reference to the outer class if it is in use or the class is
Serializable.
---
.../javac/handlers/HandleUtilityClass.java | 24 ++++++++++---------
.../after-delombok/UtilityClassInner.java | 3 ++-
.../resource/after-ecj/UtilityClassInner.java | 4 ++--
.../resource/before/UtilityClassInner.java | 3 ++-
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java
index b20aee3a..bc171b8f 100644
--- a/src/core/lombok/javac/handlers/HandleUtilityClass.java
+++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2021 The Project Lombok Authors.
+ * Copyright (C) 2015-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
@@ -107,7 +107,7 @@ public class HandleUtilityClass extends JavacAnnotationHandler {
if ((typeDecl.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0) markStatic = false;
}
- if (markStatic) classDecl.mods.flags |= Flags.STATIC;
+ if (markStatic) markClassAsStatic(classDecl);
for (JavacNode element : typeNode.down()) {
if (element.getKind() == Kind.FIELD) {
@@ -125,21 +125,23 @@ public class HandleUtilityClass extends JavacAnnotationHandler {
methodDecl.mods.flags |= Flags.STATIC;
} else if (element.getKind() == Kind.TYPE) {
- JCClassDecl innerClassDecl = (JCClassDecl) element.get();
- innerClassDecl.mods.flags |= Flags.STATIC;
- ClassSymbol innerClassSymbol = innerClassDecl.sym;
- if (innerClassSymbol != null) {
- if (innerClassSymbol.type instanceof ClassType) {
- ((ClassType) innerClassSymbol.type).setEnclosingType(Type.noType);
- }
- innerClassSymbol.erasure_field = null;
- }
+ markClassAsStatic((JCClassDecl) element.get());
}
}
if (makeConstructor) createPrivateDefaultConstructor(typeNode);
}
+ private void markClassAsStatic(JCClassDecl classDecl) {
+ classDecl.mods.flags |= Flags.STATIC; // maybe Flags.NOOUTERTHIS too?
+ ClassSymbol innerClassSymbol = classDecl.sym;
+ if (innerClassSymbol != null && innerClassSymbol.type instanceof ClassType) {
+ ClassType classType = (ClassType) innerClassSymbol.type;
+ classType.setEnclosingType(Type.noType);
+ innerClassSymbol.erasure_field = null;
+ }
+ }
+
private void createPrivateDefaultConstructor(JavacNode typeNode) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.PRIVATE, List.nil());
diff --git a/test/transform/resource/after-delombok/UtilityClassInner.java b/test/transform/resource/after-delombok/UtilityClassInner.java
index 4c4c6743..cd91bc2d 100644
--- a/test/transform/resource/after-delombok/UtilityClassInner.java
+++ b/test/transform/resource/after-delombok/UtilityClassInner.java
@@ -1,5 +1,6 @@
+@java.lang.SuppressWarnings("serial")
class UtilityClassInner {
- static final class UtilClass {
+ static final class UtilClass implements java.io.Serializable {
@java.lang.SuppressWarnings("all")
@lombok.Generated
private UtilClass() {
diff --git a/test/transform/resource/after-ecj/UtilityClassInner.java b/test/transform/resource/after-ecj/UtilityClassInner.java
index 9086367c..31bd396c 100644
--- a/test/transform/resource/after-ecj/UtilityClassInner.java
+++ b/test/transform/resource/after-ecj/UtilityClassInner.java
@@ -1,5 +1,5 @@
-class UtilityClassInner {
- static final @lombok.experimental.UtilityClass class UtilClass {
+@java.lang.SuppressWarnings("serial") class UtilityClassInner {
+ static final @lombok.experimental.UtilityClass class UtilClass implements java.io.Serializable {
private @java.lang.SuppressWarnings("all") @lombok.Generated UtilClass() {
super();
throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
diff --git a/test/transform/resource/before/UtilityClassInner.java b/test/transform/resource/before/UtilityClassInner.java
index ccb0101b..8fd3a9e7 100644
--- a/test/transform/resource/before/UtilityClassInner.java
+++ b/test/transform/resource/before/UtilityClassInner.java
@@ -1,4 +1,5 @@
+@java.lang.SuppressWarnings("serial")
class UtilityClassInner {
@lombok.experimental.UtilityClass
- class UtilClass {}
+ class UtilClass implements java.io.Serializable {}
}
\ No newline at end of file
From 36f5fa6ceaa7dfcd98292baeaac036288debbf48 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sun, 24 Nov 2024 20:59:50 +0100
Subject: [PATCH 09/47] Add compile test step to Github Actions
---
.github/workflows/ant.yml | 29 ++++++++++++++++++++++++++++
test/manual/compileTests/.gitignore | 1 +
test/manual/compileTests/runTests.sh | 20 +++++++++++++++++++
3 files changed, 50 insertions(+)
create mode 100644 test/manual/compileTests/.gitignore
create mode 100755 test/manual/compileTests/runTests.sh
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index a216ebba..d28dc135 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -183,3 +183,32 @@ jobs:
- name: Compile in container
run: docker run --entrypoint="" -v $(pwd)/lombok.jar:/workspace/lombok.jar $IMAGE_NAME /bin/bash -c "cd classpath; ${{ matrix.tool.cmd }}"
+
+ manual-tests:
+ runs-on: ubuntu-24.04
+ needs: build
+ strategy:
+ matrix:
+ jdk: [8, 11, 17, 21, 23]
+ dir: [compileTests]
+ fail-fast: false
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Set up JDK ${{ matrix.jdk }}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ matrix.jdk }}
+ distribution: 'zulu'
+
+ - uses: actions/download-artifact@v4
+ with:
+ name: lombok.jar
+ path: dist
+
+ - name: Run tests
+ working-directory: ./test/manual/${{ matrix.dir }}/
+ run: ./runTests.sh
+
diff --git a/test/manual/compileTests/.gitignore b/test/manual/compileTests/.gitignore
new file mode 100644
index 00000000..e2e7327c
--- /dev/null
+++ b/test/manual/compileTests/.gitignore
@@ -0,0 +1 @@
+/out
diff --git a/test/manual/compileTests/runTests.sh b/test/manual/compileTests/runTests.sh
new file mode 100755
index 00000000..1b129920
--- /dev/null
+++ b/test/manual/compileTests/runTests.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+echo 'This will compile a selection of files in test/transform/resource/before. If the compilation works without error, lombok is working as designed.'
+
+mkdir -p out/
+
+# list of files to iterate over
+FILES="UtilityClassInner.java"
+BASE_PATH="../../../test/transform/resource/before"
+LOMBOK_JAR="../../../dist/lombok.jar"
+
+# compile all files in list
+for f in $FILES
+do
+
+ echo "Compiling $f"
+ javac -processorpath $LOMBOK_JAR -cp $LOMBOK_JAR -d out/ $BASE_PATH/$f
+done
+
+rm -rf out/
From b313df556d9f04b343769ba336e7a66d94e6c419 Mon Sep 17 00:00:00 2001
From: Anshuman Mishra
Date: Fri, 20 Dec 2024 23:50:39 -0800
Subject: [PATCH 10/47] fix: Don't alter the AST node positions of original
code.
---
.../javac/handlers/HandleConstructor.java | 2 +-
.../javac/handlers/HandleEqualsAndHashCode.java | 2 +-
.../lombok/javac/handlers/HandleGetter.java | 2 +-
.../javac/handlers/HandleJacksonized.java | 2 +-
.../lombok/javac/handlers/HandleSetter.java | 4 ++--
src/core/lombok/javac/handlers/HandleWith.java | 4 ++--
.../lombok/javac/handlers/HandleWithBy.java | 2 +-
.../lombok/javac/handlers/JavacHandlerUtil.java | 17 +++++++++++------
.../javac/handlers/JavacSingularsRecipes.java | 4 ++--
9 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java
index 31d15445..ca885cd6 100644
--- a/src/core/lombok/javac/handlers/HandleConstructor.java
+++ b/src/core/lombok/javac/handlers/HandleConstructor.java
@@ -364,7 +364,7 @@ public class HandleConstructor {
if (addConstructorProperties && !isLocalType(typeNode) && LombokOptionsFactory.getDelombokOptions(typeNode.getContext()).getFormatPreferences().generateConstructorProperties()) {
addConstructorProperties(mods, typeNode, fieldsToParam);
}
- if (onConstructor != null) mods.annotations = mods.annotations.appendList(copyAnnotations(onConstructor));
+ if (onConstructor != null) mods.annotations = mods.annotations.appendList(copyAnnotations(onConstructor, maker));
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName(""),
null, List.nil(), params.toList(), List.nil(),
maker.Block(0L, nullChecks.appendList(assigns).toList()), null), source);
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index 259880fa..40854a34 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -190,7 +190,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler {
List copyableAnnotations = findCopyableAnnotations(field);
List delegates = findDelegatesAndRemoveFromField(field);
- List annsOnMethod = copyAnnotations(onMethod).appendList(copyableAnnotations);
+ List annsOnMethod = copyAnnotations(onMethod, field.getTreeMaker()).appendList(copyableAnnotations);
if (field.isFinal()) {
if (getCheckerFrameworkVersion(field).generatePure()) annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genTypeRef(field, CheckerFrameworkVersion.NAME__PURE), List.nil()));
} else {
diff --git a/src/core/lombok/javac/handlers/HandleJacksonized.java b/src/core/lombok/javac/handlers/HandleJacksonized.java
index 3ee0eec4..bec2d771 100644
--- a/src/core/lombok/javac/handlers/HandleJacksonized.java
+++ b/src/core/lombok/javac/handlers/HandleJacksonized.java
@@ -136,7 +136,7 @@ public class HandleJacksonized extends JavacAnnotationHandler {
// Copy annotations from the class to the builder class.
List copyableAnnotations = findJacksonAnnotationsOnClass(tdNode);
- List copiedAnnotations = copyAnnotations(copyableAnnotations);
+ List copiedAnnotations = copyAnnotations(copyableAnnotations, maker);
for (JCAnnotation anno : copiedAnnotations) {
recursiveSetGeneratedBy(anno, annotationNode);
}
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 380f71ca..bdb5b1ac 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -241,7 +241,7 @@ public class HandleSetter extends JavacAnnotationHandler {
List copyableAnnotations = findCopyableAnnotations(field);
Name methodName = field.toName(setterName);
- List annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations);
+ List annsOnParam = copyAnnotations(onParam, treeMaker).appendList(copyableAnnotations);
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
JCExpression pType = cloneType(treeMaker, fieldDecl.vartype, source);
@@ -274,7 +274,7 @@ public class HandleSetter extends JavacAnnotationHandler {
List throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
- List annsOnMethod = mergeAnnotations(copyAnnotations(onMethod), findCopyableToSetterAnnotations(field));
+ List annsOnMethod = mergeAnnotations(copyAnnotations(onMethod, treeMaker), findCopyableToSetterAnnotations(field));
if (isFieldDeprecated(field) || deprecate) {
annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.nil()));
}
diff --git a/src/core/lombok/javac/handlers/HandleWith.java b/src/core/lombok/javac/handlers/HandleWith.java
index c7fa0531..52f2c192 100644
--- a/src/core/lombok/javac/handlers/HandleWith.java
+++ b/src/core/lombok/javac/handlers/HandleWith.java
@@ -229,7 +229,7 @@ public class HandleWith extends JavacAnnotationHandler {
JCBlock methodBody = null;
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
- List annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations);
+ List annsOnParam = copyAnnotations(onParam, maker).appendList(copyableAnnotations);
JCExpression pType = cloneType(maker, fieldDecl.vartype, source);
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, pType, null);
@@ -278,7 +278,7 @@ public class HandleWith extends JavacAnnotationHandler {
List throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
- List annsOnMethod = copyAnnotations(onMethod);
+ List annsOnMethod = copyAnnotations(onMethod, maker);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(source);
if (checkerFramework.generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.nil()));
diff --git a/src/core/lombok/javac/handlers/HandleWithBy.java b/src/core/lombok/javac/handlers/HandleWithBy.java
index ff67fd9f..7978928f 100644
--- a/src/core/lombok/javac/handlers/HandleWithBy.java
+++ b/src/core/lombok/javac/handlers/HandleWithBy.java
@@ -321,7 +321,7 @@ public class HandleWithBy extends JavacAnnotationHandler {
List throwsClauses = List.nil();
JCExpression annotationMethodDefaultValue = null;
- List annsOnMethod = copyAnnotations(onMethod);
+ List annsOnMethod = copyAnnotations(onMethod, maker);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(source);
if (checkerFramework.generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.nil()));
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 38658bb6..15c47a93 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1746,7 +1746,8 @@ public class JavacHandlerUtil {
}
}
}
- return copyAnnotations(result.toList());
+
+ return copyAnnotations(result.toList(), node.getTreeMaker());
}
/**
@@ -1784,7 +1785,7 @@ public class JavacHandlerUtil {
if (annoName == null) return List.nil();
if (!annoName.isEmpty()) {
- for (String bn : annotationsToFind) if (typeMatches(bn, node, annoName)) return List.of(anno);
+ for (String bn : annotationsToFind) if (typeMatches(bn, node, annoName)) return copyAnnotations(List.of(anno), node.getTreeMaker());
}
ListBuffer result = new ListBuffer();
@@ -1799,7 +1800,7 @@ public class JavacHandlerUtil {
}
}
}
- return copyAnnotations(result.toList());
+ return copyAnnotations(result.toList(), node.getTreeMaker());
}
/**
@@ -2108,14 +2109,18 @@ public class JavacHandlerUtil {
errorNode.addError(out.append(" are not allowed on builder classes.").toString());
}
- static List copyAnnotations(List extends JCExpression> in) {
+ static List copyAnnotations(List extends JCExpression> in, JavacTreeMaker maker) {
ListBuffer out = new ListBuffer();
for (JCExpression expr : in) {
if (!(expr instanceof JCAnnotation)) continue;
- out.append((JCAnnotation) expr.clone());
+ out.append(copyAnnotation((JCAnnotation) expr, maker));
}
return out.toList();
}
+
+ static JCAnnotation copyAnnotation(JCAnnotation annotation, JavacTreeMaker maker) {
+ return maker.Annotation(annotation.annotationType, annotation.args);
+ }
static List mergeAnnotations(List a, List b) {
if (a == null || a.isEmpty()) return b;
@@ -2266,7 +2271,7 @@ public class JavacHandlerUtil {
if (JCAnnotatedTypeReflect.is(in)) {
JCExpression underlyingType = cloneType0(maker, JCAnnotatedTypeReflect.getUnderlyingType(in));
- List anns = copyAnnotations(JCAnnotatedTypeReflect.getAnnotations(in));
+ List anns = copyAnnotations(JCAnnotatedTypeReflect.getAnnotations(in), maker);
return JCAnnotatedTypeReflect.create(anns, underlyingType);
}
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 4954a610..938d6e8f 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -315,7 +315,7 @@ public class JavacSingularsRecipes {
if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(source, setterPrefix, name.toString()));
statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
- List methodAnnotations = copyAnnotations(findCopyableToBuilderSingularSetterAnnotations(data.annotation.up()));
+ List methodAnnotations = copyAnnotations(findCopyableToBuilderSingularSetterAnnotations(data.annotation.up()), maker);
finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, methodAnnotations, access, null);
}
@@ -362,7 +362,7 @@ public class JavacSingularsRecipes {
statements.prepend(JavacHandlerUtil.generateNullCheck(maker, null, data.getPluralName(), builderType, "%s cannot be null"));
}
- List methodAnnotations = copyAnnotations(findCopyableToSetterAnnotations(data.annotation.up()));
+ List methodAnnotations = copyAnnotations(findCopyableToSetterAnnotations(data.annotation.up()), maker);
finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), methodAnnotations, access, ignoreNullCollections);
}
From 3bd40aaa4551e4121012651610066bd41966b969 Mon Sep 17 00:00:00 2001
From: ZZZank <47418975+ZZZank@users.noreply.github.com>
Date: Mon, 23 Dec 2024 15:59:30 +0800
Subject: [PATCH 11/47] update gradle syntax to support both `.gradle` and
`.gradle.kts`
---
website/templates/setup/gradle.html | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/website/templates/setup/gradle.html b/website/templates/setup/gradle.html
index 69e2e71f..10c40e43 100644
--- a/website/templates/setup/gradle.html
+++ b/website/templates/setup/gradle.html
@@ -23,11 +23,11 @@ repositories {
}
dependencies {
- compileOnly 'org.projectlombok:lombok:${version}'
- annotationProcessor 'org.projectlombok:lombok:${version}'
+ compileOnly("org.projectlombok:lombok:${version}")
+ annotationProcessor("org.projectlombok:lombok:${version}")
- testCompileOnly 'org.projectlombok:lombok:${version}'
- testAnnotationProcessor 'org.projectlombok:lombok:${version}'
+ testCompileOnly("org.projectlombok:lombok:${version}")
+ testAnnotationProcessor("org.projectlombok:lombok:${version}")
}
Remember that you still have to download lombok.jar (or find it in gradle's caches) and run it as a jarfile, if you wish to program in eclipse. The plugin makes that part easier.
From fab7ffdc2b5b04358ffd28e38c8e071817a4decb Mon Sep 17 00:00:00 2001
From: Anshuman Mishra
Date: Fri, 27 Dec 2024 14:34:00 -0800
Subject: [PATCH 12/47] Add unit test and cover missing cases
---
.../javac/handlers/JavacHandlerUtil.java | 7 +-
src/delombok/lombok/delombok/Delombok.java | 6 ++
test/core/src/lombok/RunTestsViaDelombok.java | 66 +++++++++++++++++--
3 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 15c47a93..5c9f80c6 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -38,6 +38,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
+import com.sun.source.tree.TreeVisitor;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
@@ -75,6 +76,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.tree.JCTree.TypeBoundKind;
+import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.Context;
@@ -2117,9 +2119,10 @@ public class JavacHandlerUtil {
}
return out.toList();
}
-
+
static JCAnnotation copyAnnotation(JCAnnotation annotation, JavacTreeMaker maker) {
- return maker.Annotation(annotation.annotationType, annotation.args);
+ TreeVisitor visitor = new TreeCopier(maker.getUnderlyingTreeMaker());
+ return (JCAnnotation) visitor.visitAnnotation(annotation, null);
}
static List mergeAnnotations(List a, List b) {
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index e5fb440e..a0510f6c 100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -103,6 +103,7 @@ public class Delombok {
private LinkedHashMap fileToBase = new LinkedHashMap();
private List filesToParse = new ArrayList();
private Map formatPrefs = new HashMap();
+ private List preLombokProcessors = new ArrayList();
private List additionalAnnotationProcessors = new ArrayList();
/** If null, output to standard out. */
@@ -653,6 +654,10 @@ public class Delombok {
fileToBase.put(f, base);
}
+ public void addPreLombokProcessors(AbstractProcessor processor) {
+ preLombokProcessors.add(processor);
+ }
+
public void addAdditionalAnnotationProcessor(AbstractProcessor processor) {
additionalAnnotationProcessors.add(processor);
}
@@ -735,6 +740,7 @@ public class Delombok {
Map baseMap = new IdentityHashMap();
Set processors = new LinkedHashSet();
+ processors.addAll(preLombokProcessors);
processors.add(new lombok.javac.apt.LombokProcessor());
processors.addAll(additionalAnnotationProcessors);
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java
index 918a0de4..1051cec8 100644
--- a/test/core/src/lombok/RunTestsViaDelombok.java
+++ b/test/core/src/lombok/RunTestsViaDelombok.java
@@ -33,6 +33,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
@@ -83,7 +85,11 @@ public class RunTestsViaDelombok extends AbstractRunTests {
delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, result.getMessages()));
- if (parameters.isCheckPositions()) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion()));
+ if (parameters.isCheckPositions()) {
+ NodePositionMapper nodePositionMapper = new NodePositionMapper();
+ delombok.addPreLombokProcessors(nodePositionMapper);
+ delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion(), nodePositionMapper));
+ }
delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor());
delombok.addAdditionalAnnotationProcessor(new ValidateNoDuplicateTreeNodeProcessor());
@@ -105,15 +111,35 @@ public class RunTestsViaDelombok extends AbstractRunTests {
}
}
+ public static class NodePositionMapper extends TreeProcessor {
+ Map nodePositions = new HashMap<>();
+
+ @Override void processCompilationUnit(final JCCompilationUnit unit) {
+ unit.accept(new TreeScanner() {
+ @Override public void scan(JCTree tree) {
+ if (tree == null) return;
+ if (tree.pos >= 0) {
+ nodePositions.put(tree, tree.pos);
+ }
+ super.scan(tree);
+
+ }
+ });
+ }
+
+ }
+
public static class ValidatePositionProcessor extends TreeProcessor {
private final int version;
+ private final NodePositionMapper nodePositionMapper;
- public ValidatePositionProcessor(int version) {
+ public ValidatePositionProcessor(int version, NodePositionMapper nodePositionMapper) {
this.version = version;
+ this.nodePositionMapper = nodePositionMapper;
}
private String craftFailMsg(String problematicNode, Deque astContext) {
- StringBuilder msg = new StringBuilder(problematicNode).append(" position of node not set: ");
+ StringBuilder msg = new StringBuilder(problematicNode);
for (JCTree t : astContext) {
msg.append("\n ").append(t.getClass().getSimpleName());
String asStr = t.toString();
@@ -125,12 +151,30 @@ public class RunTestsViaDelombok extends AbstractRunTests {
return msg.append("\n-------").toString();
}
+ private boolean isLombokGenerated(JCTree tree) {
+ List annotations = com.sun.tools.javac.util.List.nil();
+ if (tree instanceof JCMethodDecl) {
+ annotations = ((JCMethodDecl) tree).mods.annotations;
+ }
+ if (tree instanceof JCVariableDecl) {
+ annotations = ((JCVariableDecl) tree).mods.annotations;
+ }
+ for (JCAnnotation annotation: annotations) {
+ if ("lombok.Generated".equals(annotation.getAnnotationType().toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override void processCompilationUnit(final JCCompilationUnit unit) {
final Deque astContext = new ArrayDeque();
+ final Deque lombokGeneratedNodes = new ArrayDeque();
unit.accept(new TreeScanner() {
@Override public void scan(JCTree tree) {
if (tree == null) return;
if (tree instanceof JCMethodDecl && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) return;
+ if (isLombokGenerated(tree)) lombokGeneratedNodes.add(tree);
astContext.push(tree);
try {
if (tree instanceof JCModifiers) return;
@@ -153,16 +197,26 @@ public class RunTestsViaDelombok extends AbstractRunTests {
if (tree instanceof JCVariableDecl && (((JCVariableDecl) tree).mods.flags & Javac.GENERATED_MEMBER) != 0) return;
- if (check && tree.pos == -1) fail(craftFailMsg("Start", astContext));
+ if (check && tree.pos == -1) fail(craftFailMsg("Start position of node not set: ", astContext));
+ // Ignore ast position validation on lombok generated nodes.
+ if (lombokGeneratedNodes.isEmpty()) {
+ Integer expectedPos = nodePositionMapper.nodePositions.get(tree);
+ if (expectedPos != null && !expectedPos.equals(tree.pos)) {
+ fail(craftFailMsg(String.format("Expected node position %d, actual node position %d: ", expectedPos, tree.pos), astContext));
+ }
+ }
if (check && Javac.getEndPosition(tree, unit) == -1) {
- fail(craftFailMsg("End", astContext));
+ fail(craftFailMsg("End position of node not set: ", astContext));
}
} finally {
try {
super.scan(tree);
} finally {
- astContext.pop();
+ JCTree _tree = astContext.pop();
+ if (!lombokGeneratedNodes.isEmpty() && lombokGeneratedNodes.peek().equals(_tree)) {
+ lombokGeneratedNodes.pop();
+ }
}
}
}
From d32de67f16c762c0ca56502c55670e31ab9b295d Mon Sep 17 00:00:00 2001
From: Anshuman Mishra
Date: Sat, 28 Dec 2024 09:34:28 -0800
Subject: [PATCH 13/47] Syntax as pre Pre JDK 8
---
test/core/src/lombok/RunTestsViaDelombok.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java
index 1051cec8..8b3efc17 100644
--- a/test/core/src/lombok/RunTestsViaDelombok.java
+++ b/test/core/src/lombok/RunTestsViaDelombok.java
@@ -112,7 +112,7 @@ public class RunTestsViaDelombok extends AbstractRunTests {
}
public static class NodePositionMapper extends TreeProcessor {
- Map nodePositions = new HashMap<>();
+ Map nodePositions = new HashMap();
@Override void processCompilationUnit(final JCCompilationUnit unit) {
unit.accept(new TreeScanner() {
From 9536c297eac49753792dcc20297e0e043661f209 Mon Sep 17 00:00:00 2001
From: Anshuman Mishra
Date: Fri, 3 Jan 2025 13:04:26 -0800
Subject: [PATCH 14/47] Remove annotation skip for duplicate check
---
AUTHORS | 1 +
test/core/src/lombok/RunTestsViaDelombok.java | 9 ---------
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index a8c9bcc4..ebbc5b37 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,6 +4,7 @@ Adam Juraszek
Aleksandr Zhelezniak
Amine Touzani
Andre Brait
+Anshuman Mishra
Bulgakov Alexander
Caleb Brinkman
Christian Nüssgens
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java
index 8b3efc17..80eb24be 100644
--- a/test/core/src/lombok/RunTestsViaDelombok.java
+++ b/test/core/src/lombok/RunTestsViaDelombok.java
@@ -34,7 +34,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Locale;
@@ -343,14 +342,6 @@ public class RunTestsViaDelombok extends AbstractRunTests {
super.scan(tree);
parents.pop();
}
-
- /**
- * We always generate shallow copies for annotations
- */
- @Override
- public void visitAnnotation(JCAnnotation tree) {
- return;
- }
});
}
From ba3c92236096be9896d4d37404b62a2193ce9607 Mon Sep 17 00:00:00 2001
From: Anshuman Mishra
Date: Fri, 3 Jan 2025 13:08:23 -0800
Subject: [PATCH 15/47] Nit
---
src/core/lombok/javac/handlers/HandleGetter.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 41d4e092..03dd566c 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -250,7 +250,7 @@ public class HandleGetter extends JavacAnnotationHandler {
List copyableAnnotations = findCopyableAnnotations(field);
List delegates = findDelegatesAndRemoveFromField(field);
- List annsOnMethod = copyAnnotations(onMethod, field.getTreeMaker()).appendList(copyableAnnotations);
+ List annsOnMethod = copyAnnotations(onMethod, treeMaker).appendList(copyableAnnotations);
if (field.isFinal()) {
if (getCheckerFrameworkVersion(field).generatePure()) annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genTypeRef(field, CheckerFrameworkVersion.NAME__PURE), List.nil()));
} else {
From 9f9668f18b731118c67c6e31f09f36f612a0a038 Mon Sep 17 00:00:00 2001
From: Roel Spilker
Date: Tue, 7 Jan 2025 10:38:22 +0100
Subject: [PATCH 16/47] Remove Fern as sponsor
---
README.md | 6 ------
1 file changed, 6 deletions(-)
diff --git a/README.md b/README.md
index 88fc6e53..afc38a72 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,5 @@
# Project Lombok
-Sponsored Content
-> [](https://form.typeform.com/to/bShdJw7z)
-> Offer API docs that look as good as Stripe's using our sponsor [Fern](https://form.typeform.com/to/bShdJw7z). Request a [preview of your docs](https://form.typeform.com/to/bShdJw7z) on Fern.
-
-
-
**Project Lombok** is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, automate your logging variables, and much more.
From 5b445406a7a7bbc15858f9106a77484dadd275db Mon Sep 17 00:00:00 2001
From: Jacob van Lingen
Date: Wed, 8 Jan 2025 16:37:25 +0100
Subject: [PATCH 17/47] Update onXExample_pre.jpage
Update `onX` example, to make the JDK 8 `onConstructor` syntax more clear.
---
website/usageExamples/experimental/onXExample_pre.jpage | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/website/usageExamples/experimental/onXExample_pre.jpage b/website/usageExamples/experimental/onXExample_pre.jpage
index e54371ae..9222531d 100644
--- a/website/usageExamples/experimental/onXExample_pre.jpage
+++ b/website/usageExamples/experimental/onXExample_pre.jpage
@@ -7,7 +7,8 @@ import javax.persistence.Id;
import javax.persistence.Column;
import javax.validation.constraints.Max;
-@AllArgsConstructor(onConstructor=@__(@Inject))
+// @AllArgsConstructor(onConstructor=@__(@Inject)) //JDK7
+@AllArgsConstructor(onConstructor_=@Inject) //JDK8
public class OnXExample {
// @Getter(onMethod=@__({@Id, @Column(name="unique-id")})) //JDK7
// @Setter(onParam=@__(@Max(10000))) //JDK7
From 03fb4cb1108d1090cbd0a42f16bf46eaabaeef2d Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Tue, 28 Jan 2025 23:29:09 +0100
Subject: [PATCH 18/47] [fixes #3781] Replace inefficient Javadoc Regex
---
.../lombok/core/handlers/HandlerUtil.java | 6 +-
.../eclipse/handlers/EclipseHandlerUtil.java | 6 +-
.../after-delombok/GetterSetterJavadoc.java | 204 ++++++++++++++++++
.../after-ecj/GetterSetterJavadoc.java | 145 +++++++++++++
.../resource/before/GetterSetterJavadoc.java | 64 ++++++
5 files changed, 419 insertions(+), 6 deletions(-)
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index 412a7741..0e91edf6 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2024 The Project Lombok Authors.
+ * Copyright (C) 2013-2025 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
@@ -906,7 +906,7 @@ public class HandlerUtil {
private Pattern pattern;
JavadocTag(String regexpFragment) {
- pattern = Pattern.compile("\\s?^[ \\t]*\\**[ \\t]*" + regexpFragment + "(\\S|\\s)*?(?=(\\s^\\s*\\**\\s*@|\\Z))", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ pattern = Pattern.compile("\\s?^[ \\t]*\\**[ \\t]*" + regexpFragment + ".*?(?=(\\s^\\s*\\**\\s*@|\\Z))", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
}
}
@@ -978,7 +978,7 @@ public class HandlerUtil {
public static String getParamJavadoc(String methodComment, String param) {
if (methodComment == null || methodComment.isEmpty()) return methodComment;
- Pattern pattern = Pattern.compile("@param " + param + " (\\S|\\s)+?(?=^ ?@|\\z)", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
+ Pattern pattern = Pattern.compile("@param " + param + " .+?(?=^ ?@|\\z)", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(methodComment);
if (matcher.find()) {
return matcher.group();
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 4fc948a6..94b05779 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2024 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -2799,8 +2799,8 @@ public class EclipseHandlerUtil {
return annotations;
}
- private static final Pattern JAVADOC_PATTERN = Pattern.compile("^\\s*\\/\\*\\*((?:\\S|\\s)*?)\\*\\/", Pattern.MULTILINE);
- private static final Pattern LEADING_ASTERISKS_PATTERN = Pattern.compile("(?m)^\\s*\\* ?");
+ private static final Pattern JAVADOC_PATTERN = Pattern.compile("^\\s*\\/\\*\\*(.*?)\\*\\/", Pattern.MULTILINE | Pattern.DOTALL);
+ private static final Pattern LEADING_ASTERISKS_PATTERN = Pattern.compile("^\\s*\\* ?", Pattern.MULTILINE);
public static String getDocComment(EclipseNode eclipseNode) {
if (eclipseNode.getAst().getSource() == null) return null;
diff --git a/test/transform/resource/after-delombok/GetterSetterJavadoc.java b/test/transform/resource/after-delombok/GetterSetterJavadoc.java
index 76afbd2d..f1bb0324 100644
--- a/test/transform/resource/after-delombok/GetterSetterJavadoc.java
+++ b/test/transform/resource/after-delombok/GetterSetterJavadoc.java
@@ -163,3 +163,207 @@ class GetterSetterJavadoc5 {
return this;
}
}
+class GetterSetterJavadocLong {
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ */
+ private String userId;
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public GetterSetterJavadocLong() {
+ }
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ */
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public String getUserId() {
+ return this.userId;
+ }
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ *
+ * @param userId the unique identifier assigned to a user. This value must be non-null
+ * and conform to the format defined by the system. Passing a null or
+ * invalid ID may result in an {@link IllegalArgumentException} or
+ * similar error.
+ * @param databaseConnection the connection to the database used for retrieving or
+ * persisting the user ID. This parameter is required for
+ * database-related operations and must be properly closed
+ * after use to prevent resource leaks.
+ * @param userRole the role associated with the user (e.g., "admin", "user", "guest").
+ * This parameter may influence access control and permissions
+ * granted to the user within the system.
+ */
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public void setUserId(final String userId) {
+ this.userId = userId;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public boolean equals(final java.lang.Object o) {
+ if (o == this) return true;
+ if (!(o instanceof GetterSetterJavadocLong)) return false;
+ final GetterSetterJavadocLong other = (GetterSetterJavadocLong) o;
+ if (!other.canEqual((java.lang.Object) this)) return false;
+ final java.lang.Object this$userId = this.getUserId();
+ final java.lang.Object other$userId = other.getUserId();
+ if (this$userId == null ? other$userId != null : !this$userId.equals(other$userId)) return false;
+ return true;
+ }
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ protected boolean canEqual(final java.lang.Object other) {
+ return other instanceof GetterSetterJavadocLong;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public int hashCode() {
+ final int PRIME = 59;
+ int result = 1;
+ final java.lang.Object $userId = this.getUserId();
+ result = result * PRIME + ($userId == null ? 43 : $userId.hashCode());
+ return result;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public java.lang.String toString() {
+ return "GetterSetterJavadocLong(userId=" + this.getUserId() + ")";
+ }
+}
diff --git a/test/transform/resource/after-ecj/GetterSetterJavadoc.java b/test/transform/resource/after-ecj/GetterSetterJavadoc.java
index 03ac4075..89b6af5a 100644
--- a/test/transform/resource/after-ecj/GetterSetterJavadoc.java
+++ b/test/transform/resource/after-ecj/GetterSetterJavadoc.java
@@ -132,3 +132,148 @@ class GetterSetterJavadoc3 {
return this;
}
}
+@lombok.Data class GetterSetterJavadocLong {
+ private String userId;
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ */
+ public @java.lang.SuppressWarnings("all") @lombok.Generated String getUserId() {
+ return this.userId;
+ }
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ *
+ * @param userId the unique identifier assigned to a user. This value must be non-null
+ * and conform to the format defined by the system. Passing a null or
+ * invalid ID may result in an {@link IllegalArgumentException} or
+ * similar error.
+ * @param databaseConnection the connection to the database used for retrieving or
+ * persisting the user ID. This parameter is required for
+ * database-related operations and must be properly closed
+ * after use to prevent resource leaks.
+ * @param userRole the role associated with the user (e.g., "admin", "user", "guest").
+ * This parameter may influence access control and permissions
+ * granted to the user within the system.
+ */
+ public @java.lang.SuppressWarnings("all") @lombok.Generated void setUserId(final String userId) {
+ this.userId = userId;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") @lombok.Generated boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof GetterSetterJavadocLong)))
+ return false;
+ final GetterSetterJavadocLong other = (GetterSetterJavadocLong) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ final java.lang.Object this$userId = this.getUserId();
+ final java.lang.Object other$userId = other.getUserId();
+ if (((this$userId == null) ? (other$userId != null) : (! this$userId.equals(other$userId))))
+ return false;
+ return true;
+ }
+ protected @java.lang.SuppressWarnings("all") @lombok.Generated boolean canEqual(final java.lang.Object other) {
+ return (other instanceof GetterSetterJavadocLong);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") @lombok.Generated int hashCode() {
+ final int PRIME = 59;
+ int result = 1;
+ final java.lang.Object $userId = this.getUserId();
+ result = ((result * PRIME) + (($userId == null) ? 43 : $userId.hashCode()));
+ return result;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") @lombok.Generated java.lang.String toString() {
+ return (("GetterSetterJavadocLong(userId=" + this.getUserId()) + ")");
+ }
+ public @java.lang.SuppressWarnings("all") @lombok.Generated GetterSetterJavadocLong() {
+ super();
+ }
+}
\ No newline at end of file
diff --git a/test/transform/resource/before/GetterSetterJavadoc.java b/test/transform/resource/before/GetterSetterJavadoc.java
index 2ad46f8d..b14f2c02 100644
--- a/test/transform/resource/before/GetterSetterJavadoc.java
+++ b/test/transform/resource/before/GetterSetterJavadoc.java
@@ -62,3 +62,67 @@ class GetterSetterJavadoc5 {
*/
@lombok.Getter @lombok.Setter private int fieldName;
}
+
+@lombok.Data
+class GetterSetterJavadocLong {
+ /**
+ * This field represents the unique identifier for a user in the system. It is used
+ * throughout the application to uniquely identify and retrieve user-related data.
+ * The ID is typically generated by the database and is guaranteed to be unique
+ * within the context of the system.
+ *
+ * The ID is an integral part of various operations, including but not limited to:
+ *
+ * - Authenticating users during login processes.
+ * - Associating user-specific preferences and settings.
+ * - Tracking user activity and logs for auditing purposes.
+ * - Facilitating relationships between users and other entities such as orders,
+ * messages, or roles within the system.
+ *
+ *
+ * Key characteristics of the {@code userId} field:
+ *
+ * - Immutability: Once assigned, the ID must not be modified to
+ * ensure data integrity.
+ * - Security: Access to this field should be controlled to prevent
+ * unauthorized modifications or data leakage.
+ * - Uniqueness: The ID must be unique within the system. For
+ * distributed systems, consider using GUIDs or UUIDs to avoid collisions.
+ *
+ *
+ * Example usage:
+ *
+ * User user = userService.getUserById(userId);
+ * if (user != null) {
+ * System.out.println("User found: " + user.getName());
+ * } else {
+ * System.out.println("User not found.");
+ * }
+ *
+ *
+ * Developers should ensure that the ID complies with constraints imposed by the
+ * database schema, such as length and format restrictions. Furthermore, it is
+ * recommended to validate the ID before persisting or using it in critical operations.
+ *
+ *
For methods or constructors that accept the {@code userId} as a parameter, the
+ * following guidelines should be followed:
+ *
+ * - Validate the format of the ID to ensure it adheres to system requirements.
+ * - Handle null or empty values gracefully, providing appropriate error messages
+ * or default behavior where necessary.
+ *
+ *
+ * @param userId the unique identifier assigned to a user. This value must be non-null
+ * and conform to the format defined by the system. Passing a null or
+ * invalid ID may result in an {@link IllegalArgumentException} or
+ * similar error.
+ * @param databaseConnection the connection to the database used for retrieving or
+ * persisting the user ID. This parameter is required for
+ * database-related operations and must be properly closed
+ * after use to prevent resource leaks.
+ * @param userRole the role associated with the user (e.g., "admin", "user", "guest").
+ * This parameter may influence access control and permissions
+ * granted to the user within the system.
+ */
+ private String userId;
+}
From fd0dfb64f970ae0b9262c9badefee8227882e827 Mon Sep 17 00:00:00 2001
From: tiennm99
Date: Tue, 4 Feb 2025 21:06:52 +0700
Subject: [PATCH 19/47] docs(locked): fix introduced version
---
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 fa041975..a3fef167 100644
--- a/website/templates/features/Locked.html
+++ b/website/templates/features/Locked.html
@@ -3,7 +3,7 @@
<@f.scaffold title="@Locked" logline="Pop it and lock it! ReentrantLock, now with less hassle.">
<@f.history>
- @Locked was introduced in lombok v1.20.
+ @Locked was introduced in lombok v1.18.32.
@f.history>
From 97b2096e1f9093d9d61886563b35b36a075a5e50 Mon Sep 17 00:00:00 2001
From: Snjezana Peco
Date: Mon, 10 Feb 2025 13:19:05 +0100
Subject: [PATCH 20/47] Fix RuntimeException in Javac$JavadocOps
Signed-off-by: Snjezana Peco
---
src/stubs/com/sun/tools/javac/parser/Tokens.java | 4 ++++
src/utils/lombok/javac/Javac.java | 7 ++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/stubs/com/sun/tools/javac/parser/Tokens.java b/src/stubs/com/sun/tools/javac/parser/Tokens.java
index f86bcefa..62e98ffd 100644
--- a/src/stubs/com/sun/tools/javac/parser/Tokens.java
+++ b/src/stubs/com/sun/tools/javac/parser/Tokens.java
@@ -1,5 +1,7 @@
package com.sun.tools.javac.parser;
+import com.sun.tools.javac.util.JCDiagnostic;
+
public class Tokens {
public static class Token {
public int pos;
@@ -12,6 +14,8 @@ public class Tokens {
String getText();
+ JCDiagnostic.DiagnosticPosition getPos();
+
int getSourcePos(int index);
CommentStyle getStyle();
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index f7834687..7966fb81 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -55,6 +55,7 @@ import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import lombok.core.ClassLiteral;
@@ -381,6 +382,10 @@ public class Javac {
@Override public boolean isDeprecated() {
return text.contains("@deprecated") && field instanceof JCVariableDecl && isFieldDeprecated(field);
}
+
+ @Override public DiagnosticPosition getPos() {
+ return field;
+ }
};
}
}
@@ -416,7 +421,7 @@ public class Javac {
throw sneakyThrow(e.getCause());
}
}
-
+
public static void storeEnd(JCTree tree, int pos, JCCompilationUnit top) {
try {
Object endPositions = JCCOMPILATIONUNIT_ENDPOSITIONS.get(top);
From 9b37daa9da737992c515b76dcb4d5910a371a87e Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Wed, 19 Feb 2025 23:30:48 +0100
Subject: [PATCH 21/47] [fixes #3830] Detect @Delegate on record components
---
.../eclipse/handlers/EclipseHandlerUtil.java | 16 +++++++++++-----
.../lombok/eclipse/agent/PatchDelegate.java | 17 +++++++++++++----
.../after-delombok/DelegateOnRecord.java | 8 ++++++++
.../resource/after-ecj/DelegateOnRecord.java | 8 ++++++++
.../resource/before/DelegateOnRecord.java | 6 ++++++
5 files changed, 46 insertions(+), 9 deletions(-)
create mode 100644 test/transform/resource/after-delombok/DelegateOnRecord.java
create mode 100644 test/transform/resource/after-ecj/DelegateOnRecord.java
create mode 100644 test/transform/resource/before/DelegateOnRecord.java
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 4fc948a6..8151e8cc 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2024 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -2736,10 +2736,8 @@ public class EclipseHandlerUtil {
* Returns {@code true} if the provided node is a record declaration (so, not an annotation definition, interface, enum, or plain class).
*/
public static boolean isRecord(EclipseNode typeNode) {
- TypeDeclaration typeDecl = null;
- if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
- int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
- return (modifiers & AccRecord) != 0;
+ ASTNode node = typeNode.get();
+ return node instanceof TypeDeclaration && isRecord((TypeDeclaration) node);
}
/**
@@ -2773,6 +2771,14 @@ public class EclipseHandlerUtil {
return typeNode.isStatic() || typeNode.up() == null || typeNode.up().getKind() == Kind.COMPILATION_UNIT || isRecord(typeNode);
}
+ /**
+ * Returns {@code true} if the provided type declaration is a record declaration (so, not an annotation definition, interface, enum, or plain class).
+ */
+ public static boolean isRecord(TypeDeclaration typeDecl) {
+ int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
+ return (modifiers & AccRecord) != 0;
+ }
+
public static AbstractVariableDeclaration[] getRecordComponents(TypeDeclaration typeDeclaration) {
if (typeDeclaration == null || (typeDeclaration.modifiers & AccRecord) == 0) return null;
try {
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index fee6db43..547810e9 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2024 The Project Lombok Authors.
+ * Copyright (C) 2010-2025 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
@@ -48,13 +48,13 @@ import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
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.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
@@ -129,7 +129,8 @@ public class PatchDelegate {
}
private static boolean hasDelegateMarkedFieldsOrMethods(TypeDeclaration decl) {
- if (decl.fields != null) for (FieldDeclaration field : decl.fields) {
+ AbstractVariableDeclaration[] fields = getFieldsOrRecordComponents(decl);
+ if (fields != null) for (AbstractVariableDeclaration field : fields) {
if (field.annotations == null) continue;
for (Annotation ann : field.annotations) {
if (isDelegate(ann, decl)) return true;
@@ -224,11 +225,19 @@ public class PatchDelegate {
Annotation_applied.set(annotation, true);
}
+ private static AbstractVariableDeclaration[] getFieldsOrRecordComponents(TypeDeclaration decl) {
+ if (isRecord(decl)) return getRecordComponents(decl);
+ return decl.fields;
+ }
+
private static void fillMethodBindingsForFields(CompilationUnitDeclaration cud, ClassScope scope, List methodsToDelegate) {
TypeDeclaration decl = scope.referenceContext;
if (decl == null) return;
- if (decl.fields != null) for (FieldDeclaration field : decl.fields) {
+ AbstractVariableDeclaration[] fields = getFieldsOrRecordComponents(decl);
+ if (fields == null) return;
+
+ for (AbstractVariableDeclaration field : fields) {
if (field.annotations == null) continue;
for (Annotation ann : field.annotations) {
if (!isDelegate(ann, decl)) continue;
diff --git a/test/transform/resource/after-delombok/DelegateOnRecord.java b/test/transform/resource/after-delombok/DelegateOnRecord.java
new file mode 100644
index 00000000..fc5b9744
--- /dev/null
+++ b/test/transform/resource/after-delombok/DelegateOnRecord.java
@@ -0,0 +1,8 @@
+// version 14:
+record DelegateOnRecord(Runnable runnable) {
+ @java.lang.SuppressWarnings("all")
+ @lombok.Generated
+ public void run() {
+ this.runnable.run();
+ }
+}
diff --git a/test/transform/resource/after-ecj/DelegateOnRecord.java b/test/transform/resource/after-ecj/DelegateOnRecord.java
new file mode 100644
index 00000000..7194a014
--- /dev/null
+++ b/test/transform/resource/after-ecj/DelegateOnRecord.java
@@ -0,0 +1,8 @@
+// version 14:
+import lombok.experimental.Delegate;
+record DelegateOnRecord(Runnable runnable) {
+/* Implicit */ private final Runnable runnable;
+ public @java.lang.SuppressWarnings("all") @lombok.Generated void run() {
+ this.runnable.run();
+ }
+}
diff --git a/test/transform/resource/before/DelegateOnRecord.java b/test/transform/resource/before/DelegateOnRecord.java
new file mode 100644
index 00000000..daaeba5b
--- /dev/null
+++ b/test/transform/resource/before/DelegateOnRecord.java
@@ -0,0 +1,6 @@
+//platform !eclipse: Requires a 'full' eclipse with intialized workspace, and we don't (yet) have that set up properly in the test run.
+//version 14:
+import lombok.experimental.Delegate;
+
+record DelegateOnRecord(@Delegate Runnable runnable) {
+}
From 4404ef9bb24ee7e3f65d554c70f8df63dc019384 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Tue, 25 Feb 2025 22:33:15 +0100
Subject: [PATCH 22/47] [fixes #3805] Create copies for expressions
---
.../handlers/HandleEqualsAndHashCode.java | 4 +--
src/core/lombok/javac/handlers/HandleLog.java | 11 +++---
.../lombok/javac/handlers/HandleNonNull.java | 21 ++++++-----
.../javac/handlers/JavacHandlerUtil.java | 9 ++---
test/core/src/lombok/RunTestsViaDelombok.java | 35 ++++---------------
5 files changed, 27 insertions(+), 53 deletions(-)
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index 40854a34..07610a0b 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2021 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -185,7 +185,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandlernil(), method, List.nil());
break;
case TOPIC:
- if (loggerTopic instanceof JCLiteral) {
- expressions[i] = maker.Literal(((JCLiteral) loggerTopic).value);
- } else {
- expressions[i] = cloneType(maker, loggerTopic, typeNode);
- }
+ JCExpression topicExpression = copyExpression(loggerTopic, maker);
+ recursiveSetGeneratedBy(topicExpression, typeNode);
+ expressions[i] = topicExpression;
break;
case NULL:
expressions[i] = maker.Literal(CTC_BOT, null);
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index e817916d..d75ff7cf 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2021 The Project Lombok Authors.
+ * Copyright (C) 2013-2025 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
@@ -94,17 +94,17 @@ public class HandleNonNull extends JavacAnnotationHandler {
JCModifiers mods = maker.Modifiers(toJavacModifier(AccessLevel.PUBLIC) | COMPACT_RECORD_CONSTRUCTOR, List.nil());
JCBlock body = maker.Block(0L, List.nil());
- if (existingCtr == null) {
- JCMethodDecl constr = maker.MethodDef(mods, typeNode.toName(""), null, List.nil(), params.toList(), List.nil(), body, null);
- return recursiveSetGeneratedBy(constr, source);
+ JCMethodDecl constuctor = existingCtr;
+ if (constuctor == null) {
+ constuctor = maker.MethodDef(mods, typeNode.toName(""), null, List.nil(), params.toList(), List.nil(), body, null);
} else {
- existingCtr.mods = mods;
- existingCtr.body = body;
- existingCtr = recursiveSetGeneratedBy(existingCtr, source);
- addSuppressWarningsAll(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
- addGenerated(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
- return existingCtr;
+ constuctor.mods = mods;
+ constuctor.body = body;
}
+ recursiveSetGeneratedBy(constuctor, source);
+ addSuppressWarningsAll(constuctor.mods, typeNode, source, typeNode.getContext());
+ addGenerated(constuctor.mods, typeNode, source, typeNode.getContext());
+ return constuctor;
}
/**
@@ -132,7 +132,6 @@ public class HandleNonNull extends JavacAnnotationHandler {
if (md.name.contentEquals("")) {
if ((md.mods.flags & Flags.GENERATEDCONSTR) != 0) {
existingCtr = md;
- existingCtr.mods.flags = existingCtr.mods.flags & ~Flags.GENERATEDCONSTR;
generateConstructor = true;
} else {
if (!isTolerate(typeNode, md)) {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 5c9f80c6..afa0408e 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2022 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -2115,14 +2115,15 @@ public class JavacHandlerUtil {
ListBuffer out = new ListBuffer();
for (JCExpression expr : in) {
if (!(expr instanceof JCAnnotation)) continue;
- out.append(copyAnnotation((JCAnnotation) expr, maker));
+ out.append(copyExpression((JCAnnotation) expr, maker));
}
return out.toList();
}
- static JCAnnotation copyAnnotation(JCAnnotation annotation, JavacTreeMaker maker) {
+ @SuppressWarnings("unchecked")
+ static T copyExpression(T expression, JavacTreeMaker maker) {
TreeVisitor visitor = new TreeCopier(maker.getUnderlyingTreeMaker());
- return (JCAnnotation) visitor.visitAnnotation(annotation, null);
+ return (T) expression.accept(visitor, null);
}
static List mergeAnnotations(List a, List b) {
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java
index 80eb24be..8175fb71 100644
--- a/test/core/src/lombok/RunTestsViaDelombok.java
+++ b/test/core/src/lombok/RunTestsViaDelombok.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2024 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -117,6 +117,7 @@ public class RunTestsViaDelombok extends AbstractRunTests {
unit.accept(new TreeScanner() {
@Override public void scan(JCTree tree) {
if (tree == null) return;
+ if (tree instanceof JCMethodDecl && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) return;
if (tree.pos >= 0) {
nodePositions.put(tree, tree.pos);
}
@@ -150,30 +151,12 @@ public class RunTestsViaDelombok extends AbstractRunTests {
return msg.append("\n-------").toString();
}
- private boolean isLombokGenerated(JCTree tree) {
- List annotations = com.sun.tools.javac.util.List.nil();
- if (tree instanceof JCMethodDecl) {
- annotations = ((JCMethodDecl) tree).mods.annotations;
- }
- if (tree instanceof JCVariableDecl) {
- annotations = ((JCVariableDecl) tree).mods.annotations;
- }
- for (JCAnnotation annotation: annotations) {
- if ("lombok.Generated".equals(annotation.getAnnotationType().toString())) {
- return true;
- }
- }
- return false;
- }
-
@Override void processCompilationUnit(final JCCompilationUnit unit) {
final Deque astContext = new ArrayDeque();
- final Deque lombokGeneratedNodes = new ArrayDeque();
unit.accept(new TreeScanner() {
@Override public void scan(JCTree tree) {
if (tree == null) return;
if (tree instanceof JCMethodDecl && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) return;
- if (isLombokGenerated(tree)) lombokGeneratedNodes.add(tree);
astContext.push(tree);
try {
if (tree instanceof JCModifiers) return;
@@ -198,12 +181,9 @@ public class RunTestsViaDelombok extends AbstractRunTests {
if (check && tree.pos == -1) fail(craftFailMsg("Start position of node not set: ", astContext));
- // Ignore ast position validation on lombok generated nodes.
- if (lombokGeneratedNodes.isEmpty()) {
- Integer expectedPos = nodePositionMapper.nodePositions.get(tree);
- if (expectedPos != null && !expectedPos.equals(tree.pos)) {
- fail(craftFailMsg(String.format("Expected node position %d, actual node position %d: ", expectedPos, tree.pos), astContext));
- }
+ Integer expectedPos = nodePositionMapper.nodePositions.get(tree);
+ if (expectedPos != null && !expectedPos.equals(tree.pos)) {
+ fail(craftFailMsg(String.format("Expected node position %d, actual node position %d: ", expectedPos, tree.pos), astContext));
}
if (check && Javac.getEndPosition(tree, unit) == -1) {
fail(craftFailMsg("End position of node not set: ", astContext));
@@ -212,10 +192,7 @@ public class RunTestsViaDelombok extends AbstractRunTests {
try {
super.scan(tree);
} finally {
- JCTree _tree = astContext.pop();
- if (!lombokGeneratedNodes.isEmpty() && lombokGeneratedNodes.peek().equals(_tree)) {
- lombokGeneratedNodes.pop();
- }
+ astContext.pop();
}
}
}
From 94e6a38b0af6a7993a6c4211118598aaed1c660e Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Thu, 6 Mar 2025 23:23:50 +0100
Subject: [PATCH 23/47] [deps] Update dep to patcher 0.54
---
.../org.projectlombok-lombok.patcher-0.54.xml | 14 ++++++++++++++
buildScripts/ivy.xml | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.54.xml
diff --git a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.54.xml b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.54.xml
new file mode 100644
index 00000000..5779f3a3
--- /dev/null
+++ b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.54.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml
index ec30d337..d27a20ad 100644
--- a/buildScripts/ivy.xml
+++ b/buildScripts/ivy.xml
@@ -41,7 +41,7 @@
-
+
From 2e7e61372a4b18a84028c95c15b0d484556fe3c8 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sun, 9 Feb 2025 13:17:54 +0100
Subject: [PATCH 24/47] [fixes #3814] Ignore missing UNKNOWN type tag
---
src/utils/lombok/javac/Javac.java | 13 +++++++++++--
src/utils/lombok/javac/TreeMirrorMaker.java | 4 ++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index f7834687..d8b4740c 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2024 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -184,7 +184,16 @@ public class Javac {
public static final TypeTag CTC_NONE = typeTag("NONE");
public static final TypeTag CTC_BOT = typeTag("BOT");
public static final TypeTag CTC_ERROR = typeTag("ERROR");
- public static final TypeTag CTC_UNKNOWN = typeTag("UNKNOWN");
+ public static final TypeTag CTC_UNKNOWN; // Removed in JDK24
+ static {
+ TypeTag unknonwTypeTag = null;
+ try {
+ unknonwTypeTag = typeTag("UNKNOWN");
+ } catch (Exception e) {
+ if (!(e instanceof NoSuchFieldException)) throw Javac.sneakyThrow(e);
+ }
+ CTC_UNKNOWN = unknonwTypeTag;
+ }
public static final TypeTag CTC_UNDETVAR = typeTag("UNDETVAR");
public static final TypeTag CTC_CLASS = typeTag("CLASS");
diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java
index 44e26ab6..798a687a 100644
--- a/src/utils/lombok/javac/TreeMirrorMaker.java
+++ b/src/utils/lombok/javac/TreeMirrorMaker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2021 The Project Lombok Authors.
+ * Copyright (C) 2010-2025 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
@@ -105,7 +105,7 @@ public class TreeMirrorMaker extends TreeCopier {
boolean wipeSymAndType = copy.type.isErroneous();
if (!wipeSymAndType) {
TypeTag typeTag = TypeTag.typeTag(copy.type);
- wipeSymAndType = (CTC_NONE.equals(typeTag) || CTC_ERROR.equals(typeTag) || CTC_UNKNOWN.equals(typeTag) || CTC_UNDETVAR.equals(typeTag));
+ wipeSymAndType = (typeTag.equals(CTC_NONE) || typeTag.equals(CTC_ERROR) || typeTag.equals(CTC_UNKNOWN) || typeTag.equals(CTC_UNDETVAR));
}
if (wipeSymAndType) {
From 2d91eb8c8b6ba3c463d3e5b4441181429290cee1 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sun, 9 Feb 2025 17:54:41 +0100
Subject: [PATCH 25/47] [jdk24] Use getRecordComponents instead of
findRecordComponentToRemove
---
.../javac/handlers/JavacHandlerUtil.java | 34 +++++++++++--------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 5c9f80c6..fff1846a 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2022 The Project Lombok Authors.
+ * Copyright (C) 2009-2025 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
@@ -592,38 +592,42 @@ public class JavacHandlerUtil {
private static final Field astField;
private static final Field originalAnnos;
- private static final Method findRecordComponentToRemove;
+ private static final Method getRecordComponents = Permit.permissiveGetMethod(ClassSymbol.class, "getRecordComponents");
static {
Field a = null;
Field o = null;
- Method m = null;
try {
Class> forName = Class.forName("com.sun.tools.javac.code.Symbol$RecordComponent");
a = Permit.permissiveGetField(forName, "ast");
o = Permit.permissiveGetField(forName, "originalAnnos");
- m = Permit.permissiveGetMethod(ClassSymbol.class, "findRecordComponentToRemove", JCVariableDecl.class);
} catch (Throwable e) {
// Ignore
}
astField = a;
originalAnnos = o;
- findRecordComponentToRemove = m;
}
static void deleteAnnotation(JCClassDecl record, JCVariableDecl component, JCTree annotation) {
- if ((astField == null && originalAnnos == null) || findRecordComponentToRemove == null) return;
+ if ((astField == null && originalAnnos == null) || getRecordComponents == null) return;
try {
- Object toRemove = Permit.invokeSneaky(findRecordComponentToRemove, record.sym, component);
- if (astField != null) {
- // OpenJDK
- JCVariableDecl variable = Permit.get(astField, toRemove);
- variable.mods.annotations = filterListByPos(variable.mods.annotations, annotation);
- } else {
- // Zulu JDK 17
- List annotations = Permit.get(originalAnnos, toRemove);
- Permit.set(originalAnnos, toRemove, filterListByPos(annotations, annotation));
+ List> recordComponents = (List>) Permit.invokeSneaky(getRecordComponents, record.sym);
+
+ for (Object recordComponent : recordComponents) {
+ Name recordComponentName = ((Symbol) recordComponent).name;
+ if (!recordComponentName.equals(component.name)) continue;
+
+ if (astField != null) {
+ // OpenJDK
+ JCVariableDecl variable = Permit.get(astField, recordComponent);
+ variable.mods.annotations = filterListByPos(variable.mods.annotations, annotation);
+ } else {
+ // Zulu JDK 17
+ List annotations = Permit.get(originalAnnos, recordComponent);
+ Permit.set(originalAnnos, recordComponent, filterListByPos(annotations, annotation));
+ }
+ return;
}
} catch (Throwable e) {
// Ignore
From 02de4f415e28102af247747dbbca73a8017231b0 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Thu, 6 Mar 2025 23:38:30 +0100
Subject: [PATCH 26/47] [jdk24] Add JDK 24 test step
---
.github/workflows/ant.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index a216ebba..ca99193a 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -41,10 +41,10 @@ jobs:
runs-on: ubuntu-24.04
needs: build
env:
- EA_JDK: 23
+ EA_JDK: 24
strategy:
matrix:
- jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
+ jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
goal: [javacCurrent]
include:
- jdk: 11
From 1fea6e7cfba759f0f9ded348cb0f7e747237b929 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 7 Mar 2025 00:20:19 +0100
Subject: [PATCH 27/47] [refactor] Fixed a typo in a local var name, and
utility-method-ified it to then make that typo a moot point.
---
src/utils/lombok/javac/Javac.java | 14 +++-----------
src/utils/lombok/javac/JavacTreeMaker.java | 11 ++++++++++-
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java
index d8b4740c..2924f0af 100644
--- a/src/utils/lombok/javac/Javac.java
+++ b/src/utils/lombok/javac/Javac.java
@@ -22,7 +22,7 @@
package lombok.javac;
import static lombok.javac.JavacTreeMaker.TreeTag.treeTag;
-import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
+import static lombok.javac.JavacTreeMaker.TypeTag.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -184,16 +184,8 @@ public class Javac {
public static final TypeTag CTC_NONE = typeTag("NONE");
public static final TypeTag CTC_BOT = typeTag("BOT");
public static final TypeTag CTC_ERROR = typeTag("ERROR");
- public static final TypeTag CTC_UNKNOWN; // Removed in JDK24
- static {
- TypeTag unknonwTypeTag = null;
- try {
- unknonwTypeTag = typeTag("UNKNOWN");
- } catch (Exception e) {
- if (!(e instanceof NoSuchFieldException)) throw Javac.sneakyThrow(e);
- }
- CTC_UNKNOWN = unknonwTypeTag;
- }
+ public static final TypeTag CTC_UNKNOWN = typeTagPermissive("UNKNOWN"); // UNKNOWN has been removed in JDK24, hence, we need to look it up permissively (just make it `null` if it does not exist).
+
public static final TypeTag CTC_UNDETVAR = typeTag("UNDETVAR");
public static final TypeTag CTC_CLASS = typeTag("CLASS");
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
index 04f0e208..c49db768 100644
--- a/src/utils/lombok/javac/JavacTreeMaker.java
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2020 The Project Lombok Authors.
+ * Copyright (C) 2013-2025 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
@@ -258,6 +258,15 @@ public class JavacTreeMaker {
public static TypeTag typeTag(String identifier) {
return new TypeTag(getFieldCached(TYPE_TAG_CACHE, Javac.getJavaCompilerVersion() < 8 ? "com.sun.tools.javac.code.TypeTags" : "com.sun.tools.javac.code.TypeTag", identifier));
}
+
+ public static TypeTag typeTagPermissive(String identifier) {
+ try {
+ return typeTag(identifier);
+ } catch (Exception e) {
+ if (e instanceof NoSuchFieldException) return null;
+ throw Javac.sneakyThrow(e);
+ }
+ }
}
public static class TreeTag extends SchroedingerType {
From 141d3deb9771a6d3c980a00eee23affb8dcdcb69 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 7 Mar 2025 00:25:27 +0100
Subject: [PATCH 28/47] [trivial] removed a warning
---
src/core/lombok/javac/handlers/HandleNonNull.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index e817916d..3b2bcc74 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -307,7 +307,7 @@ public class HandleNonNull extends JavacAnnotationHandler {
if (invocation.args.isEmpty()) return null;
JCExpression firstArgument = invocation.args.head;
if (!(firstArgument instanceof JCIdent)) return null;
- return ((JCIdent) firstArgument).toString();
+ return firstArgument.toString();
}
if (isIf) {
From 38046234084a3703f148bb4f48e5ebb3d670e0f1 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 7 Mar 2025 00:26:10 +0100
Subject: [PATCH 29/47] [build] update 'test v current JDK' from 23 to 24, as
JDK24 is about to go gold.
---
buildScripts/tests.ant.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml
index c9d4a2b4..caed9496 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -1,5 +1,5 @@
-
-
+
+
From b208a063a159e4f0020769d2f621513b5690f53b Mon Sep 17 00:00:00 2001
From: Roel Spilker
Date: Fri, 7 Mar 2025 09:17:58 +0100
Subject: [PATCH 30/47] [trivial] make test.broad work again
---
buildScripts/tests.ant.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml
index caed9496..42d55098 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -372,5 +372,5 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
+
From da533a87e30e345b3993271693dc4e7899498c33 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 28 Mar 2025 16:08:09 +0100
Subject: [PATCH 31/47] [build] Add eclipse 2025-03 deps and test targets, and
cleaned up some old ones.
---
buildScripts/ivy.xml | 82 +++++++-------------------------------
buildScripts/setup.ant.xml | 20 ++--------
buildScripts/tests.ant.xml | 52 ++++--------------------
3 files changed, 26 insertions(+), 128 deletions(-)
diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml
index d27a20ad..ee4c39db 100644
--- a/buildScripts/ivy.xml
+++ b/buildScripts/ivy.xml
@@ -30,12 +30,8 @@
-
-
-
-
-
+
@@ -112,44 +108,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -163,31 +121,19 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml
index abd8d386..7c7667bc 100644
--- a/buildScripts/setup.ant.xml
+++ b/buildScripts/setup.ant.xml
@@ -160,28 +160,16 @@ 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 42d55098..3fe241b6 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -198,11 +198,6 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
-
-
-
@@ -217,29 +212,14 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -302,28 +282,12 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
+
@@ -371,6 +335,6 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
+
+
From 49bacef01a3e831100a2fb036ec9852cf1839227 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 28 Mar 2025 16:26:55 +0100
Subject: [PATCH 32/47] [bugfix][ecj] For checkerframework: We failed to mark
end pos on generated annotations.
---
src/core/lombok/eclipse/handlers/HandleBuilder.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index a63d3b36..161de8ca 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -794,6 +794,7 @@ public class HandleBuilder extends EclipseAnnotationHandler {
}
ann.memberValue = arr;
}
+ ann.declarationSourceEnd = pE;
TypeReference typeReference = job.createBuilderTypeReference();
int len = typeReference.getTypeName().length;
From f158f2c24151181eaf5cb1a1ff4d76c822ebb2ac Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Fri, 28 Mar 2025 16:35:45 +0100
Subject: [PATCH 33/47] [changelog] JDK24 support mentioned in the changelog
now
---
doc/changelog.markdown | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 469a638c..54d4e41d 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,7 +2,7 @@ Lombok Changelog
----------------
### v1.18.37 "Edgy Guinea Pig"
-* We recently released v1.18.36; there is no edge release since then.
+* PLATFORM: JDK24 support added.
### v1.18.36 (November 15th, 2024)
* PLATFORM: JDK23 support added.
From 02cb2834fb15223e6bfa2cb969a387427c07c021 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 00:25:00 +0100
Subject: [PATCH 34/47] [trivial]
---
src/utils/lombok/permit/Permit.java | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java
index 477f06c1..d58a35e6 100644
--- a/src/utils/lombok/permit/Permit.java
+++ b/src/utils/lombok/permit/Permit.java
@@ -132,16 +132,15 @@ public class Permit {
public static Field getField(Class> c, String fName) throws NoSuchFieldException {
Field f = null;
- Class> oc = c;
- while (c != null) {
+ Class> d = c;
+ while (d != null) {
try {
- f = c.getDeclaredField(fName);
+ f = d.getDeclaredField(fName);
break;
} catch (NoSuchFieldException e) {}
- c = c.getSuperclass();
+ d = d.getSuperclass();
}
-
- if (f == null) throw new NoSuchFieldException(oc.getName() + " :: " + fName);
+ if (f == null) throw new NoSuchFieldException(c.getName() + " :: " + fName);
return setAccessible(f);
}
From 36be69b1c4bd90c8b0704752f9a50323d1dfec2e Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 00:26:14 +0100
Subject: [PATCH 35/47] [docs][fixes #3853] Update maven instructions: You need
to explicitly specify lombok is an annotation processor.
---
website/templates/_download-edge.html | 28 +++++++++++++++++++++++-
website/templates/setup/maven.html | 31 ++++++++++++++++-----------
2 files changed, 45 insertions(+), 14 deletions(-)
diff --git a/website/templates/_download-edge.html b/website/templates/_download-edge.html
index 0e04596c..7b98d3b2 100644
--- a/website/templates/_download-edge.html
+++ b/website/templates/_download-edge.html
@@ -10,7 +10,13 @@
- You can use the edge release from maven using the projectlombok.org repository:
+ You can use the edge release from maven using the projectlombok.org repository.
+ This requires:
+ - Adding the lombok maven repository to your
repositories section
+ - Adding lombok as a dependency to your project in the
dependencies section, specifying version edge-SNAPSHOT.
+ - Adding lombok as an annotation processor in the
annotationProcessorPaths section, specifying version edge-SNAPSHOT.
+
+ These sections in your pom file should look like this:
<repositories>
<repository>
<id>projectlombok.org</id>
@@ -26,6 +32,26 @@
<scope>provided</scope>
</dependency>
</dependencies>
+
+<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>edge-SNAPSHOT</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+</build>
+
+
You can use the edge release from gradle using the projectlombok.org repository:
diff --git a/website/templates/setup/maven.html b/website/templates/setup/maven.html
index f6c36822..27153cb3 100644
--- a/website/templates/setup/maven.html
+++ b/website/templates/setup/maven.html
@@ -22,20 +22,25 @@
</dependencies>
- @s.section>
-
- <@s.section title="JDK9+ with module-info.java">
- The configuration of the compiler plug-in should contain the following:
-<annotationProcessorPaths>
- <path>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>${version}</version>
- </path>
-</annotationProcessorPaths>
-
-
+ You also need to add lombok as an annotation processor. This is mandatory starting with JDK23, or JDK9+ if compiling as modules (you have
module-info.java files in your build):
+<build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>${version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+</build>
@s.section>
<@s.section title="Eclipse Compiler (ECJ/JDT)">
From 0d0aba6bef8d911482a0fb3caf601f3c57ac955a Mon Sep 17 00:00:00 2001
From: MoonFruit
Date: Tue, 4 Mar 2025 18:37:00 +0800
Subject: [PATCH 36/47] Add jspecify Nonnull/Nullable annotations
---
AUTHORS | 1 +
src/core/lombok/ConfigurationKeys.java | 3 ++-
src/core/lombok/core/configuration/NullAnnotationLibrary.java | 3 ++-
website/templates/features/configuration.html | 2 +-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index ebbc5b37..c7324be9 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -62,5 +62,6 @@ Till Brychcy
Victor Williams Stafusa da Silva
Yonatan Sherwin
Yun Zhi Lin
+MoonFruit
By adding your name to this list, you grant full and irrevocable copyright and patent indemnity to Project Lombok and all use of Project Lombok in relation to all commits you add to Project Lombok, and you certify that you have the right to do so.
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index b19dccfc..2460edd3 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -106,7 +106,7 @@ public class ConfigurationKeys {
public static final ConfigurationKey ADD_SUPPRESSWARNINGS_ANNOTATIONS = new ConfigurationKey("lombok.addSuppressWarnings", "Generate @java.lang.SuppressWarnings(\"all\") on all generated code (default: true).") {};
/**
- * lombok configuration: {@code lombok.addNullAnnotations = }one of: [{@code none}, {@code javax}, {@code eclipse}, {@code jetbrains}, {@code netbeans}, {@code androidx}, {@code android.support}, {@code checkerframework}, {@code findbugs}, {@code spring}, {@code JML}, or a custom set of fully qualified annotation types].
+ * lombok configuration: {@code lombok.addNullAnnotations = }one of: [{@code none}, {@code javax}, {@code eclipse}, {@code jetbrains}, {@code netbeans}, {@code androidx}, {@code android.support}, {@code checkerframework}, {@code findbugs}, {@code spring}, {@code JML}, {@code jspecify} or a custom set of fully qualified annotation types].
*
* Lombok generally copies relevant nullity annotations from your source code to the right places. However, sometimes lombok generates code where the nullability of some node is not dependent on something in your source code. You can configure lombok to add an appropriate nullity annotation in this case.
* - {@code none} (the default) - no annotations are added.
@@ -121,6 +121,7 @@ public class ConfigurationKeys {
* - {@code findbugs} - The annotations {@code edu.umd.cs.findbugs.annotations.NonNull} and {@code edu.umd.cs.findbugs.annotations.Nullable} are used.
* - {@code spring} - The annotations {@code org.springframework.lang.NonNull} and {@code org.springframework.lang.Nullable} are used.
* - {@code jml} - The annotations {@code org.jmlspecs.annotation.NonNull} and {@code org.jmlspecs.annotation.Nullable} are used.
+ * - {@code jspecify} - The annotations {@code org.jspecify.annotations.NonNull} and {@code org.jspecify.annotations.Nullable} are used.
* CUSTOM:fully.qualified.nonnull.annotation:fully.qualified.nullable.annotation to configure your own types; the nullable annotation (and the colon) are optional.
*
*
diff --git a/src/core/lombok/core/configuration/NullAnnotationLibrary.java b/src/core/lombok/core/configuration/NullAnnotationLibrary.java
index e1d31004..1187685f 100644
--- a/src/core/lombok/core/configuration/NullAnnotationLibrary.java
+++ b/src/core/lombok/core/configuration/NullAnnotationLibrary.java
@@ -73,7 +73,8 @@ public final class NullAnnotationLibrary implements ConfigurationValueType {
public static final NullAnnotationLibrary FINDBUGS = new NullAnnotationLibrary("findbugs", "edu.umd.cs.findbugs.annotations.NonNull", "edu.umd.cs.findbugs.annotations.Nullable", false);
public static final NullAnnotationLibrary SPRING = new NullAnnotationLibrary("spring", "org.springframework.lang.NonNull", "org.springframework.lang.Nullable", false);
public static final NullAnnotationLibrary JML = new NullAnnotationLibrary("jml", "org.jmlspecs.annotation.NonNull", "org.jmlspecs.annotation.Nullable", false);
-
+ public static final NullAnnotationLibrary JSPECIFY = new NullAnnotationLibrary("jspecify", "org.jspecify.annotations.NonNull", "org.jspecify.annotations.Nullable", true);
+
private static final List ALL_AVAILABLE;
private static final String EXAMPLE_VALUE;
diff --git a/website/templates/features/configuration.html b/website/templates/features/configuration.html
index c3c39835..b33eef40 100644
--- a/website/templates/features/configuration.html
+++ b/website/templates/features/configuration.html
@@ -87,7 +87,7 @@
lombok.addNullAnnotations = <flavor>
- Many flavors are available: javax (=JSR305; not recommended), jakarta, eclipse, jetbrains, netbeans, androidx, android.support (deprecated within android), checkerframework (recommended), findbugs, spring, jml, or define your own via CUSTOM:fully.qualified.NonNullAnnotation:fully.qualified.NullableAnnotation; if your nullity annotation is solely of the type use style (it annotates types, such as eclipse's and checkerframework's offerings, versus annotating methods and parameters), the format is CUSTOM:TYPE_USE:nonnullanno:nullableanno.
+ Many flavors are available: javax (=JSR305; not recommended), jakarta, eclipse, jetbrains, netbeans, androidx, android.support (deprecated within android), checkerframework (recommended), findbugs, spring, jml, jspecify, or define your own via CUSTOM:fully.qualified.NonNullAnnotation:fully.qualified.NullableAnnotation; if your nullity annotation is solely of the type use style (it annotates types, such as eclipse's and checkerframework's offerings, versus annotating methods and parameters), the format is CUSTOM:TYPE_USE:nonnullanno:nullableanno.
This feature was added in lombok v1.18.12.
Lombok can be configured to add @lombok.Generated annotations to all generated nodes where possible; useful for JaCoCo (which has built in support),
From 10ee0016ee0da55fcb378ece98c02718c99f8a23 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 00:40:55 +0100
Subject: [PATCH 37/47] [changelog] completing #3837: Mentioned support of
JSpecify in the changelog.
---
AUTHORS | 2 +-
doc/changelog.markdown | 1 +
website/templates/features/configuration.html | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index c7324be9..d83703de 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -37,6 +37,7 @@ Mateusz Matela
Michael Dardis
Michael Ernst
Michiel Verheul
+MoonFruit
Ole Ludwig
Pascal Bihler
Peter Grant
@@ -62,6 +63,5 @@ Till Brychcy
Victor Williams Stafusa da Silva
Yonatan Sherwin
Yun Zhi Lin
-MoonFruit
By adding your name to this list, you grant full and irrevocable copyright and patent indemnity to Project Lombok and all use of Project Lombok in relation to all commits you add to Project Lombok, and you certify that you have the right to do so.
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 54d4e41d..79eb2f77 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -3,6 +3,7 @@ Lombok Changelog
### v1.18.37 "Edgy Guinea Pig"
* PLATFORM: JDK24 support added.
+* FEATURE: Lombok's nullity annotation now supports [JSpecify](https://jspecify.dev) out of the box, using [config key](https://projectlombok.org/features/configuration) `jspecify`.
### v1.18.36 (November 15th, 2024)
* PLATFORM: JDK23 support added.
diff --git a/website/templates/features/configuration.html b/website/templates/features/configuration.html
index b33eef40..6675d61e 100644
--- a/website/templates/features/configuration.html
+++ b/website/templates/features/configuration.html
@@ -87,7 +87,7 @@
lombok.addNullAnnotations = <flavor>
- Many flavors are available: javax (=JSR305; not recommended), jakarta, eclipse, jetbrains, netbeans, androidx, android.support (deprecated within android), checkerframework (recommended), findbugs, spring, jml, jspecify, or define your own via CUSTOM:fully.qualified.NonNullAnnotation:fully.qualified.NullableAnnotation; if your nullity annotation is solely of the type use style (it annotates types, such as eclipse's and checkerframework's offerings, versus annotating methods and parameters), the format is CUSTOM:TYPE_USE:nonnullanno:nullableanno.
+ Many flavors are available: jspecify (recommended), checkerframework (recommended), jakarta, eclipse, jetbrains, netbeans, androidx, findbugs, spring, jml, javax (=JSR305; not recommended), android.support (deprecated within android), or define your own via CUSTOM:fully.qualified.NonNullAnnotation:fully.qualified.NullableAnnotation; if your nullity annotation is solely of the type use style (it annotates types, such as eclipse's and checkerframework's offerings, versus annotating methods and parameters), the format is CUSTOM:TYPE_USE:nonnullanno:nullableanno.
This feature was added in lombok v1.18.12.
Lombok can be configured to add @lombok.Generated annotations to all generated nodes where possible; useful for JaCoCo (which has built in support),
From fb269e69fdae41b59b7155a6f073ed80b70320d1 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 00:51:53 +0100
Subject: [PATCH 38/47] [docs] In addition to the previous commit: Mention that
the gradle syntax also works in kotlin based gradle.
---
website/templates/setup/gradle.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/templates/setup/gradle.html b/website/templates/setup/gradle.html
index 10c40e43..0e79007b 100644
--- a/website/templates/setup/gradle.html
+++ b/website/templates/setup/gradle.html
@@ -17,7 +17,7 @@
<@s.section title="Gradle without a plugin">
- If you don't want to use the plugin, gradle has the built-in compileOnly scope, which can be used to tell gradle to add lombok only during compilation. Your build.gradle will look like:
+ If you don't want to use the plugin, gradle has the built-in compileOnly scope, which can be used to tell gradle to add lombok only during compilation. Your build.gradle or build.gradle.kts will look like:
repositories {
mavenCentral()
}
From 47fa4c2fac728682d32a0ff456b09d6c2e2f19bf Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 00:54:34 +0100
Subject: [PATCH 39/47] [PR #3807] Suggestions applied: Remove hopeful note
that didn't pan out, removed JDK7 examples (too old to bother listing at this
point).
---
website/templates/features/experimental/onX.html | 2 --
website/usageExamples/experimental/onXExample_pre.jpage | 9 +++------
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/website/templates/features/experimental/onX.html b/website/templates/features/experimental/onX.html
index fd2e7b58..418a0a39 100644
--- a/website/templates/features/experimental/onX.html
+++ b/website/templates/features/experimental/onX.html
@@ -11,8 +11,6 @@
-
Ugly syntax. The syntax of this feature is not optimal, but it is the least convoluted syntax that could possibly work (for now!)
-
-
- Possibly java 9 will offer (much) better ways of supporting this feature.
-
Uncertainty: Future versions of javac may break this feature, and we may not be able to restore it.
diff --git a/website/usageExamples/experimental/onXExample_pre.jpage b/website/usageExamples/experimental/onXExample_pre.jpage
index 9222531d..91dc09fe 100644
--- a/website/usageExamples/experimental/onXExample_pre.jpage
+++ b/website/usageExamples/experimental/onXExample_pre.jpage
@@ -7,12 +7,9 @@ import javax.persistence.Id;
import javax.persistence.Column;
import javax.validation.constraints.Max;
-// @AllArgsConstructor(onConstructor=@__(@Inject)) //JDK7
-@AllArgsConstructor(onConstructor_=@Inject) //JDK8
+@AllArgsConstructor(onConstructor_=@Inject)
public class OnXExample {
-// @Getter(onMethod=@__({@Id, @Column(name="unique-id")})) //JDK7
-// @Setter(onParam=@__(@Max(10000))) //JDK7
- @Getter(onMethod_={@Id, @Column(name="unique-id")}) //JDK8
- @Setter(onParam_=@Max(10000)) //JDK8
+ @Getter(onMethod_={@Id, @Column(name="unique-id")})
+ @Setter(onParam_=@Max(10000))
private long unid;
}
From 8b57eaa12fdea485f783ed1aa1d61fb9b778787b Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Sun, 9 Feb 2025 23:46:44 +0100
Subject: [PATCH 40/47] [fixes #3823] Set missing source position for receiver
annotation
---
buildScripts/tests.ant.xml | 1 +
.../lombok/eclipse/handlers/HandleBuilder.java | 17 ++++++-----------
test/core/src/lombok/RunTestsViaEcj.java | 4 ++--
3 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml
index 3fe241b6..90fb89c3 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -237,6 +237,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
+
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 161de8ca..92692213 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2024 The Project Lombok Authors.
+ * Copyright (C) 2013-2025 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
@@ -59,7 +59,6 @@ import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
-import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
@@ -778,28 +777,24 @@ public class HandleBuilder extends EclipseAnnotationHandler {
if (mandatories.size() == 0) return null;
- int pS = job.source.sourceStart, pE = job.source.sourceEnd;
-
char[][] nameCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__CALLED);
- SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameCalled, poss(job.source, nameCalled.length)), pS);
+ Expression memberValue;
if (mandatories.size() == 1) {
- ann.memberValue = new StringLiteral(mandatories.get(0), 0, 0, 0);
+ memberValue = new StringLiteral(mandatories.get(0), 0, 0, 0);
} else {
ArrayInitializer arr = new ArrayInitializer();
- arr.sourceStart = pS;
- arr.sourceEnd = pE;
arr.expressions = new Expression[mandatories.size()];
for (int i = 0; i < arr.expressions.length; i++) {
- arr.expressions[i] = new StringLiteral(mandatories.get(i), pS, pE, 0);
+ arr.expressions[i] = new StringLiteral(mandatories.get(i), job.source.sourceStart, job.source.sourceEnd, 0);
}
- ann.memberValue = arr;
+ memberValue = arr;
}
ann.declarationSourceEnd = pE;
TypeReference typeReference = job.createBuilderTypeReference();
int len = typeReference.getTypeName().length;
typeReference.annotations = new Annotation[len][];
- typeReference.annotations[len - 1] = new Annotation[] {ann};
+ typeReference.annotations[len - 1] = EclipseHandlerUtil.addAnnotation(job.source, null, nameCalled, memberValue);
return new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, 0);
}
diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java
index 3a0f02e2..53008987 100644
--- a/test/core/src/lombok/RunTestsViaEcj.java
+++ b/test/core/src/lombok/RunTestsViaEcj.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2024 The Project Lombok Authors.
+ * Copyright (C) 2010-2025 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
@@ -242,7 +242,7 @@ public class RunTestsViaEcj extends AbstractRunTests {
return source;
}
};
- return AST.convertCompilationUnit(4, cud, options, false, ccu, 0, null);
+ return AST.convertCompilationUnit(8, cud, options, false, ccu, 0, null);
}
}
From 24621a1a4ab199745fd3d24661a55f75979bc536 Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Mon, 10 Feb 2025 20:29:56 +0100
Subject: [PATCH 41/47] Use JDK 21 for eclipse tests
---
.github/workflows/ant.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index 639b2030..1469fdae 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -119,10 +119,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v4
with:
- java-version: 17
+ java-version: 21
distribution: 'zulu'
- name: Cache dependencies
From fe4fdf4fff40492737906ec03a6dba87d7cc8dca Mon Sep 17 00:00:00 2001
From: Rawi01
Date: Wed, 12 Feb 2025 23:41:02 +0100
Subject: [PATCH 42/47] Add eclipse 2024-12 test targets
# Conflicts:
# buildScripts/ivy.xml
---
.github/workflows/ant.yml | 2 ++
buildScripts/setup.ant.xml | 4 ++++
buildScripts/tests.ant.xml | 9 +++++++++
3 files changed, 15 insertions(+)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index 1469fdae..94dc657e 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -100,6 +100,7 @@ jobs:
- eclipse-202403
- eclipse-202406
- eclipse-202409
+ - eclipse-202412
- eclipse-I-build
- eclipse-oxygen-full
- eclipse-2022-03-full
@@ -108,6 +109,7 @@ jobs:
- eclipse-2024-03-full
- eclipse-2024-06-full
- eclipse-2024-09-full
+ - eclipse-2024-12-full
- eclipse-I-build-full
- ecj11
- ecj14
diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml
index 7c7667bc..d6f9b156 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 90fb89c3..5a2ba1c9 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -222,6 +222,11 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
+
+
+
+
+
@@ -291,6 +296,10 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
+
+
+
+
From 7471f1a2c606406bc55d02a5de2a0597402b1c55 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 01:27:58 +0100
Subject: [PATCH 43/47] [tests] removed eclipse-2024-03 t/m 2024-12; one
eclipse a year is fine and 2025-03 is in the test set.
---
.github/workflows/ant.yml | 12 ++----------
buildScripts/setup.ant.xml | 4 ----
buildScripts/tests.ant.xml | 9 ---------
3 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index 94dc657e..ffa47016 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -95,21 +95,13 @@ jobs:
- eclipse-202006
- eclipse-202006-jdk8
- eclipse-202212
- - eclipse-202309
- - eclipse-202312
- eclipse-202403
- - eclipse-202406
- - eclipse-202409
- - eclipse-202412
+ - eclipse-202503
- eclipse-I-build
- eclipse-oxygen-full
- eclipse-2022-03-full
- - eclipse-2023-09-full
- - eclipse-2023-12-full
- eclipse-2024-03-full
- - eclipse-2024-06-full
- - eclipse-2024-09-full
- - eclipse-2024-12-full
+ - eclipse-2025-03-full
- eclipse-I-build-full
- ecj11
- ecj14
diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml
index d6f9b156..7c7667bc 100644
--- a/buildScripts/setup.ant.xml
+++ b/buildScripts/setup.ant.xml
@@ -172,10 +172,6 @@ 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 5a2ba1c9..90fb89c3 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -222,11 +222,6 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
-
-
-
@@ -296,10 +291,6 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
-
-
-
-
From 41dfb0d752c5b1b4bc38793a498a2241403497f1 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 01:34:36 +0100
Subject: [PATCH 44/47] [fix #3825] Stub compilation requires all non-core-java
classes to be stubbed.
---
src/stubs/com/sun/tools/javac/parser/Tokens.java | 2 +-
src/stubs/com/sun/tools/javac/util/JCDiagnostic.java | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
create mode 100644 src/stubs/com/sun/tools/javac/util/JCDiagnostic.java
diff --git a/src/stubs/com/sun/tools/javac/parser/Tokens.java b/src/stubs/com/sun/tools/javac/parser/Tokens.java
index 62e98ffd..8bc2e3b0 100644
--- a/src/stubs/com/sun/tools/javac/parser/Tokens.java
+++ b/src/stubs/com/sun/tools/javac/parser/Tokens.java
@@ -15,7 +15,7 @@ public class Tokens {
String getText();
JCDiagnostic.DiagnosticPosition getPos();
-
+
int getSourcePos(int index);
CommentStyle getStyle();
diff --git a/src/stubs/com/sun/tools/javac/util/JCDiagnostic.java b/src/stubs/com/sun/tools/javac/util/JCDiagnostic.java
new file mode 100644
index 00000000..74d7615b
--- /dev/null
+++ b/src/stubs/com/sun/tools/javac/util/JCDiagnostic.java
@@ -0,0 +1,5 @@
+package com.sun.tools.javac.util;
+
+public class JCDiagnostic {
+ public interface DiagnosticPosition {}
+}
From f4e5bbb31203e6cf432b76133a2c91a4c4756ba7 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 01:37:12 +0100
Subject: [PATCH 45/47] [fix #3839] Fixing a mistake in my merge of 3939.
---
src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 2 +-
src/core/lombok/eclipse/handlers/HandleBuilder.java | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index c53dbfcf..1fe09b9b 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -2143,7 +2143,7 @@ public class EclipseHandlerUtil {
for (int i = 0; i < args.length; i++) {
args[i].sourceStart = pS;
args[i].sourceEnd = pE;
- na.memberValuePairs[i] = (MemberValuePair) args[i];
+ na.memberValuePairs[i] = (MemberValuePair) args[i];
}
setGeneratedBy(na.memberValuePairs[0], source);
setGeneratedBy(na.memberValuePairs[0].value, source);
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 92692213..8e850f27 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -789,7 +789,6 @@ public class HandleBuilder extends EclipseAnnotationHandler {
}
memberValue = arr;
}
- ann.declarationSourceEnd = pE;
TypeReference typeReference = job.createBuilderTypeReference();
int len = typeReference.getTypeName().length;
From 3aa9779ef41bd9097cf47183df741bec065f2315 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
Date: Sun, 30 Mar 2025 01:46:08 +0100
Subject: [PATCH 46/47] [changelog] Mention fix for eclipse negative length
(#3823) in changelog.
---
doc/changelog.markdown | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 79eb2f77..ab8ad2e9 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -4,6 +4,7 @@ Lombok Changelog
### v1.18.37 "Edgy Guinea Pig"
* PLATFORM: JDK24 support added.
* FEATURE: Lombok's nullity annotation now supports [JSpecify](https://jspecify.dev) out of the box, using [config key](https://projectlombok.org/features/configuration) `jspecify`.
+* BUGFIX: Recent eclipse releases would get you 'negative length' error. The bug had always been in lombok but didn't matter until recent releases. [Issue #3823](https://github.com/projectlombok/lombok/issues/3823).
### v1.18.36 (November 15th, 2024)
* PLATFORM: JDK23 support added.
From 77837601a13aab5cb68005bea1ed13e0ad61e8ee Mon Sep 17 00:00:00 2001
From: Misagh Moayyed
Date: Sun, 30 Mar 2025 11:08:17 +0400
Subject: [PATCH 47/47] Fix github workflow YAML configuration
---
.github/workflows/ant.yml | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index ffa47016..f8da3f42 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -91,24 +91,23 @@ jobs:
strategy:
matrix:
version:
- - eclipse-oxygen
- - eclipse-202006
- - eclipse-202006-jdk8
- - eclipse-202212
- - eclipse-202403
- - eclipse-202503
- - eclipse-I-build
- - eclipse-oxygen-full
- - eclipse-2022-03-full
- - eclipse-2024-03-full
- - eclipse-2025-03-full
- - eclipse-I-build-full
- - ecj11
- - ecj14
- - ecj16
- - ecj19
+ - eclipse-oxygen
+ - eclipse-202006
+ - eclipse-202006-jdk8
+ - eclipse-202212
+ - eclipse-202403
+ - eclipse-202503
+ - eclipse-I-build
+ - eclipse-oxygen-full
+ - eclipse-2022-03-full
+ - eclipse-2024-03-full
+ - eclipse-2025-03-full
+ - eclipse-I-build-full
+ - ecj11
+ - ecj14
+ - ecj16
+ - ecj19
fail-fast: false
-
steps:
- name: Checkout
uses: actions/checkout@v4