diff --git a/.github/workflows/ant.yml b/.github/workflows/ant.yml
index 07a77430..278f9752 100644
--- a/.github/workflows/ant.yml
+++ b/.github/workflows/ant.yml
@@ -10,16 +10,16 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 11
- name: Cache dependencies
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
ivyCache
@@ -31,7 +31,7 @@ jobs:
- name: Build with Ant
run: ant -noinput dist
- - uses: actions/upload-artifact@v3
+ - uses: actions/upload-artifact@v4
with:
name: lombok.jar
path: dist/lombok.jar
@@ -40,9 +40,11 @@ jobs:
test-javac:
runs-on: ubuntu-latest
needs: build
+ env:
+ EA_JDK: 22
strategy:
matrix:
- jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
+ jdk: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]
goal: [javacCurrent]
include:
- jdk: 11
@@ -53,32 +55,34 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.jdk }}
- if: ${{ matrix.jdk != 21 }}
- uses: actions/setup-java@v3
+ if: ${{ matrix.jdk < env.EA_JDK }}
+ uses: actions/setup-java@v4
with:
java-version: ${{ matrix.jdk }}
distribution: 'zulu'
- - name: Set up JDK 21-ea
- if: ${{ matrix.jdk == 21 }}
+ - name: Set up JDK ${{ matrix.jdk }} Early Access release
+ if: ${{ matrix.jdk >= env.EA_JDK }}
uses: oracle-actions/setup-java@v1
with:
website: jdk.java.net
- release: 21
+ 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-1.10.13-bin.zip
- unzip apache-ant-1.10.13-bin.zip -d "${HOME}"
- echo "ANT_HOME=${HOME}/apache-ant-1.10.13" >> $GITHUB_ENV
- echo "${HOME}/apache-ant-1.10.13/bin" >> $GITHUB_PATH
+ wget https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.zip
+ unzip apache-ant-$ANT_VERSION-bin.zip -d "${HOME}"
+ echo "ANT_HOME=${HOME}/apache-ant-$ANT_VERSION" >> $GITHUB_ENV
+ echo "${HOME}/apache-ant-$ANT_VERSION/bin" >> $GITHUB_PATH
- name: Cache dependencies
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
ivyCache
@@ -101,9 +105,15 @@ jobs:
- eclipse-202006-jdk8
- eclipse-202212
- eclipse-202309
+ - eclipse-202312
+ - eclipse-202403
+ - eclipse-I-build
- eclipse-oxygen-full
- eclipse-2022-03-full
- eclipse-2023-09-full
+ - eclipse-2023-12-full
+ - eclipse-2024-03-full
+ - eclipse-I-build-full
- ecj11
- ecj14
- ecj16
@@ -112,16 +122,16 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
- name: Cache dependencies
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
ivyCache
@@ -132,7 +142,7 @@ jobs:
- name: Cache base testenv
if: ${{ !endsWith(matrix.version, 'full') }}
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
testenv
@@ -140,7 +150,7 @@ jobs:
- name: Cache full testenv
if: ${{ endsWith(matrix.version, 'full') }}
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: |
testenv
@@ -154,21 +164,23 @@ jobs:
needs: build
strategy:
matrix:
- jdk: [8, 11, 17, 21]
+ jdk: [8, 11, 17, 21, 22]
tool:
- {name: "maven", cmd: "mvn compile"}
- {name: "gradle", cmd: "gradle assemble"}
- {name: "ant", cmd: "ant dist"}
- {name: "bazel", cmd: "bazel build //:ProjectRunner"}
+ exclude:
+ - {tool: {name: "gradle", cmd: "gradle assemble"}, jdk: 22}
fail-fast: false
env:
IMAGE_NAME: lombok-${{ matrix.tool.name }}-jdk${{ matrix.jdk }}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- - uses: actions/download-artifact@v3
+ - uses: actions/download-artifact@v4
with:
name: lombok.jar
diff --git a/AUTHORS b/AUTHORS
index 167451d8..a8c9bcc4 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,6 +17,7 @@ Denis Stepanov
Emil Lundberg
Enrique da Costa Cambio
Jacob Middag
+James Yoo
Jan Matèrne
Jan Rieke
Jappe van der Hel
@@ -26,6 +27,7 @@ Kevin Chirls
Liu DongMiao
Luan Nico
Maarten Mulders
+Manu Sridharan
Mark Haynes
Mart Hagenaars
Martin O'Connor <38929043+martinoconnor@users.noreply.github.com>
@@ -34,6 +36,7 @@ Mateusz Matela
Michael Dardis
Michael Ernst
Michiel Verheul
+Ole Ludwig
Pascal Bihler
Peter Grant
Philipp Eichhorn
@@ -42,6 +45,7 @@ Pim van der Loos
Rabea Gransberger
Raul Wißfeld
Reinier Zwitserloot
+Rob Stryker
Robbert Jan Grootjans
Robert Wertman
Roel Spilker
diff --git a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml
similarity index 87%
rename from buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml
rename to buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml
index 37de93e6..e6af2118 100644
--- a/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.46.xml
+++ b/buildScripts/ivy-repo/org.projectlombok-lombok.patcher-0.50.xml
@@ -1,5 +1,5 @@
-
+
@@ -9,6 +9,6 @@
-
+
diff --git a/buildScripts/ivy.xml b/buildScripts/ivy.xml
index b165300b..c3687cb8 100644
--- a/buildScripts/ivy.xml
+++ b/buildScripts/ivy.xml
@@ -32,12 +32,14 @@
+
+
-
+
@@ -64,6 +66,7 @@
+
@@ -74,7 +77,7 @@
-
+
@@ -132,6 +135,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml
index 39954a02..2a25a9ba 100644
--- a/buildScripts/setup.ant.xml
+++ b/buildScripts/setup.ant.xml
@@ -45,25 +45,22 @@ This buildfile is part of projectlombok.org. It sets up the build itself.
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Full eclipse testing requires downloading a native SWT binding. This script knows how to download for OS = [mac, linux, or windows] and architecture = [aarch64 or x86-64]. You have something different, you unique snowflake you. Your OS: "${os.name}", Your arch: "${os.arch}".
+ Full eclipse testing requires downloading a native SWT binding. This script knows how to download for OS = [mac, linux, or windows] and architecture = [aarch64 or x86-64]. You have something different, you unique snowflake you. Your OS: "${os.name}", Your arch: "${os.arch}".
@@ -118,7 +115,7 @@ This buildfile is part of projectlombok.org. It sets up the build itself.
-
+
@@ -160,15 +157,27 @@ This buildfile is part of projectlombok.org. It sets up the build itself.
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -192,13 +201,29 @@ This buildfile is part of projectlombok.org. It sets up the build itself.
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -206,133 +231,9 @@ This buildfile is part of projectlombok.org. It sets up the build itself.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml
index c7f7a865..8f7023db 100644
--- a/buildScripts/tests.ant.xml
+++ b/buildScripts/tests.ant.xml
@@ -218,6 +218,41 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -261,6 +296,18 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index d93eb9d4..7303de17 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -1,10 +1,22 @@
Lombok Changelog
----------------
-### v1.18.31 "Edgy Guinea Pig"
+### v1.18.33 "Edgy Guinea Pig"
+* We recently released v1.18.32; there is no edge release since then.
+
+### v1.18.32 (March 20th, 2024)
+* PLATFORM: Initial JDK22 support added.
+* PLAFTORM Added support for Eclipse 2024-03. [Issue #3620](https://github.com/projectlombok/lombok/issues/3620).
+* PLATFORM: Added support for recent versions of eclipse (released Q4 2023 or later or so) which would cause failures in the eclipse logs such as `java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt…`. [Issue #3564](https://github.com/projectlombok/lombok/issues/3564).
* FEATURE: `@Locked` has been introduced. Like `@Synchronized` but with `java.util.concurrent.locks` locks instead of the `synchronized` primitive. Thanks, Pim van der Loos for the PR! [Issue #3506](https://github.com/projectlombok/lombok/issues/3506).
-* BUGFIX: Eclipse projects using the com.pro-crafting.tools:jasperreports-plugin will now compile
-* We recently released v1.18.30; there is no edge release since then.
+* NECROMANCY: Inlining a generated getter in eclipse would result in eclipse incorrectly replacing calls with `@Getter` instead of the actual field's name. [Issue #562](https://github.com/projectlombok/lombok/issues/562). This issue is almost old enough to drink. Points for dedication go to Rawi for fixing this one.
+* BUGFIX: When `@SuperBuilder` was used on a type with an annotated generic type, it would error `wrong number of type arguments`. [Issue #3592](https://github.com/projectlombok/lombok/issues/3592).
+* BUGFIX: It was possible to create an infinite build loop using `@ExtensionMethod`. [Issue #3225](https://github.com/projectlombok/lombok/issues/3225).
+* BUGFIX: Using `@Getter(lazy=true)` would fail if the expression contained a variable called `value`. [Issue #2917](https://github.com/projectlombok/lombok/issues/2917).
+* BUGFIX: Many lombok features wouldn't work properly on records contained within an outer type unless you explicitly marked it `static`. [Issue #3497](https://github.com/projectlombok/lombok/issues/3497) [Issue #3559](https://github.com/projectlombok/lombok/issues/3559).
+* BUGFIX: Eclipse projects using the `com.pro-crafting.tools:jasperreports-plugin` will now compile.
+* BUGFIX: `@FieldNameConstants` now works when generated fields are involved. [Issue #3529](https://github.com/projectlombok/lombok/issues/3529).
+* IMPROBABLE BREAKING CHANGE: For JSpecify, the package name changed from `org.jspecify.nullness` to `org.jspecify.annotations`, which might lead to a different null analysis. [Issue #3608](https://github.com/projectlombok/lombok/pull/3608).
### v1.18.30 (September 20th, 2023)
* PLATFORM: Initial JDK21 support added. [Issue #3393](https://github.com/projectlombok/lombok/issues/3393).
diff --git a/docker/gradle/Dockerfile b/docker/gradle/Dockerfile
index cfb32939..b83f7f0e 100644
--- a/docker/gradle/Dockerfile
+++ b/docker/gradle/Dockerfile
@@ -7,7 +7,7 @@ RUN provision/jdk/java-${jdk}.sh
ARG lombokjar=lombok.jar
ADD https://projectlombok.org/downloads/${lombokjar} /lombok.jar
-ARG gradle=8.3
+ARG gradle=8.5
ADD provision/gradle/gradle-${gradle}.sh provision/gradle/gradle-${gradle}.sh
RUN provision/gradle/gradle-${gradle}.sh
diff --git a/docker/gradle/readme.md b/docker/gradle/readme.md
index 5b827801..2579f032 100644
--- a/docker/gradle/readme.md
+++ b/docker/gradle/readme.md
@@ -2,11 +2,12 @@
[_(general configuration and options)_](../readme.md)
-### `ARG gradle=8.3`
+### `ARG gradle=8.5`
The gradle version to be used. Supported values:
-- `8.3` (default)
+- `8.5` (default)
+- `8.3`
- `7.6.1`
- `6.8.3`
diff --git a/docker/provision/gradle/gradle-8.5.sh b/docker/provision/gradle/gradle-8.5.sh
new file mode 100755
index 00000000..2f13a210
--- /dev/null
+++ b/docker/provision/gradle/gradle-8.5.sh
@@ -0,0 +1,4 @@
+apt-get update && apt-get install -y wget unzip
+wget https://github.com/gradle/gradle-distributions/releases/download/v8.5.0/gradle-8.5-bin.zip -O gradle.zip
+mkdir /opt/gradle && unzip -d /opt/gradle gradle.zip
+mv /opt/gradle/gradle-8.5 /opt/gradle/gradle
diff --git a/docker/provision/jdk/java-22.sh b/docker/provision/jdk/java-22.sh
old mode 100644
new mode 100755
index 08d8c00a..69135bfd
--- a/docker/provision/jdk/java-22.sh
+++ b/docker/provision/jdk/java-22.sh
@@ -1,4 +1,4 @@
apt-get update && apt-get install -y wget
-wget https://download.java.net/java/early_access/jdk22/15/GPL/openjdk-22-ea+15_linux-x64_bin.tar.gz -O jdk.tar.gz
+wget https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_linux-x64_bin.tar.gz -O jdk.tar.gz
tar -xzf jdk.tar.gz -C /opt/
-mv /opt/jdk-22 /opt/jdk
\ No newline at end of file
+mv /opt/jdk-22 /opt/jdk
diff --git a/docker/readme.md b/docker/readme.md
index deb482f5..7bd05c64 100644
--- a/docker/readme.md
+++ b/docker/readme.md
@@ -13,7 +13,7 @@ By default, this is the latest released version. You can download a specific ver
### `ARG jdk=21`
The jdk version to be used. Supported values:
-- `22`(experimental, based on openjdk early access)
+- `22`(based on openjdk GA)
- `21` (default)(based on openjdk instead of adoptium)
- `17`
- `11`
diff --git a/src/core/lombok/bytecode/FixedClassWriter.java b/src/core/lombok/bytecode/FixedClassWriter.java
index f18dc3a4..6d86fe9d 100644
--- a/src/core/lombok/bytecode/FixedClassWriter.java
+++ b/src/core/lombok/bytecode/FixedClassWriter.java
@@ -28,6 +28,10 @@ class FixedClassWriter extends ClassWriter {
FixedClassWriter(ClassReader classReader, int flags) {
super(classReader, flags);
}
+
+ FixedClassWriter(int flags) {
+ super(flags);
+ }
@Override protected String getCommonSuperClass(String type1, String type2) {
//By default, ASM will attempt to live-load the class types, which will fail if meddling with classes in an
@@ -40,4 +44,4 @@ class FixedClassWriter extends ClassWriter {
return "java/lang/Object";
}
}
-}
\ No newline at end of file
+}
diff --git a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java
index 8ae7af5b..654a308a 100644
--- a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java
+++ b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java
@@ -44,7 +44,7 @@ public class PreventNullAnalysisRemover implements PostCompilerTransformation {
byte[] fixedByteCode = fixJSRInlining(original);
ClassReader reader = new ClassReader(fixedByteCode);
- ClassWriter writer = new FixedClassWriter(reader, 0);
+ ClassWriter writer = new FixedClassWriter(0);
final AtomicBoolean changesMade = new AtomicBoolean();
diff --git a/src/core/lombok/bytecode/SneakyThrowsRemover.java b/src/core/lombok/bytecode/SneakyThrowsRemover.java
index ea1c3cec..b716245d 100644
--- a/src/core/lombok/bytecode/SneakyThrowsRemover.java
+++ b/src/core/lombok/bytecode/SneakyThrowsRemover.java
@@ -46,7 +46,7 @@ public class SneakyThrowsRemover implements PostCompilerTransformation {
byte[] fixedByteCode = fixJSRInlining(original);
ClassReader reader = new ClassReader(fixedByteCode);
- ClassWriter writer = new ClassWriter(reader, 0);
+ ClassWriter writer = new ClassWriter(0);
final AtomicBoolean changesMade = new AtomicBoolean();
diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java
index c8471879..7caf52da 100644
--- a/src/core/lombok/core/Version.java
+++ b/src/core/lombok/core/Version.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2023 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,7 +30,7 @@ public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
// Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example.
// Official builds always end in an even number. (Since 0.10.2).
- private static final String VERSION = "1.18.31";
+ private static final String VERSION = "1.18.33";
private static final String RELEASE_NAME = "Edgy Guinea Pig";
// private static final String RELEASE_NAME = "Envious Ferret";
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index e8b89aad..defa746c 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -115,6 +115,7 @@ public class HandlerUtil {
"org.eclipse.jdt.annotation.NonNull",
"org.jetbrains.annotations.NotNull",
"org.jmlspecs.annotation.NonNull",
+ "org.jspecify.annotations.NonNull",
"org.netbeans.api.annotations.common.NonNull",
"org.springframework.lang.NonNull",
"reactor.util.annotation.NonNull",
@@ -185,8 +186,8 @@ public class HandlerUtil {
"org.jetbrains.annotations.UnknownNullability",
"org.jmlspecs.annotation.NonNull",
"org.jmlspecs.annotation.Nullable",
- "org.jspecify.nullness.Nullable",
- "org.jspecify.nullness.NullnessUnspecified",
+ "org.jspecify.annotations.Nullable",
+ "org.jspecify.annotations.NonNull",
"org.netbeans.api.annotations.common.CheckForNull",
"org.netbeans.api.annotations.common.NonNull",
"org.netbeans.api.annotations.common.NullAllowed",
diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java
index 4950aeef..cd7bae76 100644
--- a/src/core/lombok/eclipse/EclipseNode.java
+++ b/src/core/lombok/eclipse/EclipseNode.java
@@ -217,7 +217,7 @@ public class EclipseNode extends lombok.core.LombokNode {
TYPE_MAP = Collections.unmodifiableMap(m);
}
- private static char[] valueName = "value".toCharArray();
+ private static char[] valueName = "$value".toCharArray();
private static char[] actualValueName = "actualValue".toCharArray();
private static final int PARENTHESIZED = (1 << ASTNode.ParenthesizedSHIFT) & ASTNode.ParenthesizedMASK;
diff --git a/src/core/lombok/eclipse/handlers/HandleLocked.java b/src/core/lombok/eclipse/handlers/HandleLocked.java
index 240a6498..ab733c97 100644
--- a/src/core/lombok/eclipse/handlers/HandleLocked.java
+++ b/src/core/lombok/eclipse/handlers/HandleLocked.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2023 The Project Lombok Authors.
+ * Copyright (C) 2021-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;
+import static lombok.eclipse.EcjAugments.ASTNode_handled;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
-import lombok.Locked;
import lombok.spi.Provides;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
/**
* Handles the {@code lombok.Locked} annotation for eclipse.
@@ -52,5 +56,11 @@ public class HandleLocked extends EclipseAnnotationHandler {
@Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);
+
+ if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
+ // This method has a body in diet mode, so we have to handle it now.
+ handle(annotation, source, annotationNode);
+ ASTNode_handled.set(source, true);
+ }
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleLockedRead.java b/src/core/lombok/eclipse/handlers/HandleLockedRead.java
index a293467a..33f2583b 100644
--- a/src/core/lombok/eclipse/handlers/HandleLockedRead.java
+++ b/src/core/lombok/eclipse/handlers/HandleLockedRead.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2023 The Project Lombok Authors.
+ * Copyright (C) 2021-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;
+import static lombok.eclipse.EcjAugments.ASTNode_handled;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
-import lombok.Locked;
import lombok.spi.Provides;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
/**
* Handles the {@code lombok.Locked.Read} annotation for eclipse.
@@ -53,5 +57,11 @@ public class HandleLockedRead extends EclipseAnnotationHandler {
@Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);
+
+ if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
+ // This method has a body in diet mode, so we have to handle it now.
+ handle(annotation, source, annotationNode);
+ ASTNode_handled.set(source, true);
+ }
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleLockedWrite.java b/src/core/lombok/eclipse/handlers/HandleLockedWrite.java
index 6192c76b..548b4d4a 100644
--- a/src/core/lombok/eclipse/handlers/HandleLockedWrite.java
+++ b/src/core/lombok/eclipse/handlers/HandleLockedWrite.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2023 The Project Lombok Authors.
+ * Copyright (C) 2021-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,15 +21,19 @@
*/
package lombok.eclipse.handlers;
+import static lombok.eclipse.EcjAugments.ASTNode_handled;
+import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+import lombok.Locked;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.eclipse.DeferUntilPostDiet;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
-import lombok.Locked;
import lombok.spi.Provides;
-import org.eclipse.jdt.internal.compiler.ast.Annotation;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
/**
* Handles the {@code lombok.Locked.Write} annotation for eclipse.
@@ -53,5 +57,11 @@ public class HandleLockedWrite extends EclipseAnnotationHandler {
@Override public void preHandle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) {
String annotationValue = annotation.getInstance().value();
HandleLockedUtil.preHandle(annotationValue, LOCK_TYPE_CLASS, LOCK_IMPL_CLASS, annotationNode);
+
+ if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
+ // This method has a body in diet mode, so we have to handle it now.
+ handle(annotation, source, annotationNode);
+ ASTNode_handled.set(source, true);
+ }
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java
index 5f0ca3fb..74d9df6f 100644
--- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java
+++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2021 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,7 @@
package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Modifier;
@@ -29,15 +30,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import lombok.ConfigurationKeys;
-import lombok.SneakyThrows;
-import lombok.core.AnnotationValues;
-import lombok.core.HandlerPriority;
-import lombok.eclipse.DeferUntilPostDiet;
-import lombok.eclipse.EclipseAnnotationHandler;
-import lombok.eclipse.EclipseNode;
-import lombok.spi.Provides;
-
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -58,6 +50,15 @@ import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import lombok.ConfigurationKeys;
+import lombok.SneakyThrows;
+import lombok.core.AnnotationValues;
+import lombok.core.HandlerPriority;
+import lombok.eclipse.DeferUntilPostDiet;
+import lombok.eclipse.EclipseAnnotationHandler;
+import lombok.eclipse.EclipseNode;
+import lombok.spi.Provides;
+
/**
* Handles the {@code lombok.HandleSneakyThrows} annotation for eclipse.
*/
@@ -76,6 +77,15 @@ public class HandleSneakyThrows extends EclipseAnnotationHandler {
}
}
+ @Override
+ public void preHandle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) {
+ if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
+ // This method has a body in diet mode, so we have to handle it now.
+ handle(annotation, ast, annotationNode);
+ ASTNode_handled.set(ast, true);
+ }
+ }
+
@Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.SNEAKY_THROWS_FLAG_USAGE, "@SneakyThrows");
diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java
index dbe363d9..c5fbcf4f 100644
--- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java
+++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2021 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,7 @@
package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.eclipse.EcjAugments.ASTNode_handled;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Modifier;
@@ -70,6 +71,12 @@ public class HandleSynchronized extends EclipseAnnotationHandler {
if (method.isAbstract()) return;
createLockField(annotation, annotationNode, new boolean[] {method.isStatic()}, false);
+
+ if (hasParsedBody(getAnnotatedMethod(annotationNode))) {
+ // This method has a body in diet mode, so we have to handle it now.
+ handle(annotation, source, annotationNode);
+ ASTNode_handled.set(source, true);
+ }
}
public char[] createLockField(AnnotationValues annotation, EclipseNode annotationNode, boolean[] isStatic, boolean reportErrors) {
diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java
index fca0d0d1..3e180d84 100644
--- a/src/core/lombok/javac/JavacNode.java
+++ b/src/core/lombok/javac/JavacNode.java
@@ -288,7 +288,7 @@ public class JavacNode extends lombok.core.LombokNode {
}
if (copyOfBoxedFieldType == null) copyOfBoxedFieldType = copyType(maker, field, source);
- Name valueName = fieldNode.toName("value");
+ Name valueName = fieldNode.toName("$value");
Name actualValueName = fieldNode.toName("actualValue");
/* java.lang.Object value = this.fieldName.get();*/ {
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 3a230437..d64daf38 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -1108,6 +1108,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler {
typeParamsForBuilderParameter.append(copySelect(maker, (JCFieldAccess) typeParam));
} else if (typeParam instanceof JCTypeApply) {
typeParamsForBuilderParameter.append(cloneType(maker, (JCTypeApply)typeParam, source));
+ } else if (JCAnnotatedTypeReflect.is(typeParam)) {
+ typeParamsForBuilderParameter.append(cloneType(maker, (JCExpression)typeParam, source));
}
}
return typeParamsForBuilderParameter;
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index a252a726..8b563824 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -2033,13 +2033,13 @@ public class JavacHandlerUtil {
public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode type, List params) {
JCClassDecl td = (JCClassDecl) type.get();
- boolean instance = (td.mods.flags & Flags.STATIC) == 0;
+ boolean instance = !type.isStatic();
return namePlusTypeParamsToTypeReference(maker, type.up(), td.name, instance, params, List.nil());
}
public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, JavacNode type, List params, List annotations) {
JCClassDecl td = (JCClassDecl) type.get();
- boolean instance = (td.mods.flags & Flags.STATIC) == 0;
+ boolean instance = !type.isStatic();
return namePlusTypeParamsToTypeReference(maker, type.up(), td.name, instance, params, annotations);
}
@@ -2051,7 +2051,7 @@ public class JavacHandlerUtil {
JCExpression r = null;
if (parentType != null && parentType.getKind() == Kind.TYPE && !parentType.getName().isEmpty()) {
JCClassDecl td = (JCClassDecl) parentType.get();
- boolean outerInstance = instance && ((td.mods.flags & Flags.STATIC) == 0);
+ boolean outerInstance = instance && !parentType.isStatic();
List outerParams = instance ? td.typarams : List.nil();
r = namePlusTypeParamsToTypeReference(maker, parentType.up(), td.name, outerInstance, outerParams, List.nil());
}
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index d7434454..85598d32 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2021 The Project Lombok Authors.
+ * Copyright (C) 2016-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -263,6 +263,14 @@ public class PrettyPrinter extends JCTree.Visitor {
return false;
}
+ private void print(Name name) {
+ if (name.isEmpty()) {
+ print("_");
+ } else {
+ print(name.toString());
+ }
+ }
+
private void print(CharSequence s) {
boolean align = needsAlign;
if (needsNewLine && !onNewLine) println();
@@ -1722,6 +1730,8 @@ public class PrettyPrinter extends JCTree.Visitor {
printPatternCaseLabel(tree);
} else if (className.endsWith("$JCRecordPattern")) { // Introduced in JDK19
printRecordPattern(tree);
+ } else if (className.endsWith("$JCAnyPattern")) { // Introduced in JDK22
+ print("_");
} else {
throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree);
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 9b6350e3..e3a52ba1 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2023 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -100,6 +100,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
patchJavadoc(sm);
patchASTConverterLiterals(sm);
patchASTNodeSearchUtil(sm);
+ patchFieldInitializer(sm);
patchPostCompileHookEcj(sm);
@@ -770,6 +771,13 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.request(StackRequest.RETURN_VALUE, StackRequest.THIS)
.wrapMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "addGeneratedDelegateMethods", "java.lang.Object[]", "java.lang.Object", "java.lang.Object"))
.build());
+
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.core.JavaElement", "getElementInfo", "org.eclipse.jdt.internal.compiler.env.IElementInfo"))
+ .request(StackRequest.THIS)
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "isDelegateSourceMethod", "boolean", "java.lang.Object"))
+ .valueMethod(new Hook("lombok.launch.PatchFixesHider$Delegate", "returnElementInfo", "java.lang.Object", "java.lang.Object"))
+ .build());
}
private static void addPatchesForValEclipse(ScriptManager sm) {
@@ -966,6 +974,14 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
}
private static void patchJavadoc(ScriptManager sm) {
+ // Moved to new package and changed to instance method in 2024-03
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IJavaElement", "boolean"))
+ .methodToWrap(new Hook("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess", "getHTMLContentFromSource", "java.lang.String", "org.eclipse.jdt.core.IJavaElement"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "getHTMLContentFromSource", "java.lang.String", "java.lang.String", "java.lang.Object", "org.eclipse.jdt.core.IJavaElement"))
+ .requestExtra(StackRequest.THIS, StackRequest.PARAM1)
+ .build());
+
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2", "getHTMLContent", "java.lang.String", "org.eclipse.jdt.core.IJavaElement", "boolean"))
.methodToWrap(new Hook("org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2", "getHTMLContentFromSource", "java.lang.String", "org.eclipse.jdt.core.IJavaElement"))
@@ -989,13 +1005,6 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.requestExtra(StackRequest.PARAM1)
.build());
- sm.addScript(ScriptBuilder.replaceMethodCall()
- .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
- .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
- .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
- .requestExtra(StackRequest.THIS)
- .build());
-
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
.fieldName("$javadoc")
.fieldType("Ljava/util/Map;")
@@ -1036,6 +1045,42 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
.build());
}
+ private static void patchFieldInitializer(ScriptManager sm) {
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
+ .targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")
+ .fieldName("$fieldInfo")
+ .fieldType("Ljava/lang/Object;")
+ .build());
+
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
+ .targetClass("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor")
+ .fieldName("$sourceFieldElementInfo")
+ .fieldType("Lorg/eclipse/jdt/internal/core/SourceFieldElementInfo;")
+ .build());
+
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeFieldInfo", "boolean", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
+ .request(StackRequest.THIS)
+ .transplant()
+ .build());
+
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
+ .methodToWrap(new Hook("org.eclipse.jdt.internal.core.SourceFieldElementInfo", "", "void"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "storeSourceFieldElementInfo", "void", "org.eclipse.jdt.internal.core.SourceFieldElementInfo", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
+ .requestExtra(StackRequest.THIS)
+ .transplant()
+ .build());
+
+ sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
+ .target(new MethodTarget("org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor", "exitField", "void", "int", "int", "int"))
+ .wrapMethod(new Hook("lombok.launch.PatchFixesHider$FieldInitializer", "overwriteInitializer", "void", "org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor"))
+ .request(StackRequest.THIS)
+ .transplant()
+ .build());
+ }
+
private static void patchCrossModuleClassLoading(ScriptManager sm) {
sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", ""))
@@ -1044,14 +1089,40 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
}
private static void patchForTests(ScriptManager sm) {
- sm.addScriptIfWitness(new String[] {"lombok/eclipse/EclipseRunner"}, ScriptBuilder.wrapReturnValue()
+ String[] ECLIPSE_TEST_CLASSES = new String[] {"lombok/transform/TestWithEcj", "lombok/eclipse/EclipseRunner"};
+
+ // Add support for javadoc in tests
+ sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.replaceMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuilder", "int", "java.lang.StringBuilder"))
+ .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "printMethod", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
+ .requestExtra(StackRequest.THIS)
+ .build());
+
+ sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.replaceMethodCall()
+ .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
+ .methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
+ .replacementMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
+ .requestExtra(StackRequest.THIS)
+ .build());
+
+ sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.wrapReturnValue()
.target(new MethodTarget("org.osgi.framework.FrameworkUtil", "getBundle", "org.osgi.framework.Bundle", "java.lang.Class"))
.request(StackRequest.RETURN_VALUE, StackRequest.PARAM1)
.wrapMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "getBundle", "java.lang.Object", "java.lang.Object", "java.lang.Class"))
.build());
- sm.addScriptIfWitness(new String[] {"lombok/transform/TestWithEcj"}, ScriptBuilder.exitEarly()
- .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print"))
+ // Remove implicit canonical constructors in tests
+ sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder"))
+ .decisionMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "isImplicitCanonicalConstructor", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "java.lang.Object"))
+ .valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuilder", "java.lang.StringBuilder", "java.lang.Object", "java.lang.StringBuilder"))
+ .request(StackRequest.THIS, StackRequest.PARAM2)
+ .transplant()
+ .build());
+
+ sm.addScriptIfWitness(ECLIPSE_TEST_CLASSES, ScriptBuilder.exitEarly()
+ .target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
.decisionMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "isImplicitCanonicalConstructor", "boolean", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "java.lang.Object"))
.valueMethod(new Hook("lombok.launch.PatchFixesHider$Tests", "returnStringBuffer", "java.lang.StringBuffer", "java.lang.Object", "java.lang.StringBuffer"))
.request(StackRequest.THIS, StackRequest.PARAM2)
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index d7b17598..fee6db43 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2021 The Project Lombok Authors.
+ * Copyright (C) 2010-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,10 +21,11 @@
*/
package lombok.eclipse.agent;
-import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.EcjAugments.*;
+import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -726,6 +727,15 @@ public class PatchDelegate {
return EclipseOnlyMethods.addGeneratedDelegateMethodsToChildren(returnValue, javaElement);
}
+ public static Object returnElementInfo(Object delegateSourceMethod) {
+ Field field = Permit.permissiveGetField(delegateSourceMethod.getClass(), "sourceMethodInfo");
+ return Permit.permissiveReadField(Object.class, field, delegateSourceMethod);
+ }
+
+ public static boolean isDelegateSourceMethod(Object sourceMethod) {
+ return sourceMethod.getClass().getName().equals("lombok.eclipse.agent.PatchDelegate$EclipseOnlyMethods$DelegateSourceMethod");
+ }
+
public static class EclipseOnlyMethods {
private static void cleanupDelegateMethods(CompilationUnitDeclaration cud) {
CompilationUnit compilationUnit = getCompilationUnit(cud);
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
index 3b89c0af..555c84b0 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchExtensionMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2023 The Project Lombok Authors.
+ * Copyright (C) 2012-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -321,9 +321,11 @@ public class PatchExtensionMethod {
MethodBinding fixedBinding = scope.getMethod(extensionMethod.declaringClass, methodCall.selector, argumentTypes.toArray(new TypeBinding[0]), methodCall);
if (fixedBinding instanceof ProblemMethodBinding) {
methodCall.arguments = originalArgs;
- if (fixedBinding.declaringClass != null) {
- PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope);
+ // Sometimes the declaring class is null, in that case we have to create a new ProblemMethodBinding using the extension method's declaring class
+ if (fixedBinding.declaringClass == null) {
+ fixedBinding = new ProblemMethodBinding(fixedBinding.selector, fixedBinding.parameters, extensionMethod.declaringClass, fixedBinding.problemId());
}
+ PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope);
} else {
// If the extension method uses varargs, the last fixed binding parameter is an array but
// the method arguments are not. Even thought we already know that the method is fine we still
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
index 673c30fd..caa94e2f 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020-2021 The Project Lombok Authors.
+ * Copyright (C) 2020-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,19 +29,15 @@ import java.util.Map;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.core.CompilationUnit;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2;
-import lombok.eclipse.handlers.EclipseHandlerUtil;
import lombok.permit.Permit;
public class PatchJavadoc {
- public static String getHTMLContentFromSource(String original, Object member) {
+ public static String getHTMLContentFromSource(Object instance, String original, Object member) {
if (original != null) {
return original;
}
@@ -58,27 +54,13 @@ public class PatchJavadoc {
String rawJavadoc = docs.get(signature);
if (rawJavadoc == null) return null;
- return Reflection.javadoc2HTML((IMember) member, (IJavaElement) member, rawJavadoc);
+ return Reflection.javadoc2HTML(instance, (IMember) member, (IJavaElement) member, rawJavadoc);
}
}
return null;
}
-
- public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuffer output, TypeDeclaration type) {
- Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit);
- if (docs != null) {
- String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration);
- String rawJavadoc = docs.get(signature);
- if (rawJavadoc != null) {
- for (String line : rawJavadoc.split("\r?\n")) {
- ASTNode.printIndent(tab, output).append(line).append("\n");
- }
- }
- }
- return methodDeclaration.print(tab, output);
- }
-
+
private static class Signature {
static final String getSignature(SourceMethod sourceMethod) {
StringBuilder sb = new StringBuilder();
@@ -103,9 +85,10 @@ public class PatchJavadoc {
private static class Reflection {
private static final Method javadoc2HTML;
private static final Method oldJavadoc2HTML;
+ private static final Method reallyOldJavadoc2HTML;
private static final Method lsJavadoc2HTML;
static {
- Method a = null, b = null, c = null;
+ Method a = null, b = null, c = null, d = null;
try {
a = Permit.getMethod(JavadocContentAccess2.class, "javadoc2HTML", IMember.class, IJavaElement.class, String.class);
@@ -116,30 +99,41 @@ public class PatchJavadoc {
try {
c = Permit.getMethod(Class.forName("org.eclipse.jdt.ls.core.internal.javadoc.JavadocContentAccess2"), "javadoc2HTML", IMember.class, IJavaElement.class, String.class);
} catch (Throwable t) {}
+ try {
+ d = Permit.getMethod(Class.forName("org.eclipse.jdt.core.manipulation.internal.javadoc.CoreJavadocAccess"), "javadoc2HTML", IMember.class, IJavaElement.class, String.class);
+ } catch (Throwable t) {}
- javadoc2HTML = a;
- oldJavadoc2HTML = b;
+ oldJavadoc2HTML = a;
+ reallyOldJavadoc2HTML = b;
lsJavadoc2HTML = c;
+ javadoc2HTML = d;
}
- private static String javadoc2HTML(IMember member, IJavaElement element, String rawJavadoc) {
+ private static String javadoc2HTML(Object instance, IMember member, IJavaElement element, String rawJavadoc) {
if (javadoc2HTML != null) {
try {
- return (String) javadoc2HTML.invoke(null, member, element, rawJavadoc);
- } catch (Throwable t) {
- return null;
- }
- }
- if (lsJavadoc2HTML != null) {
- try {
- return (String) lsJavadoc2HTML.invoke(null, member, element, rawJavadoc);
+ return (String) javadoc2HTML.invoke(instance, member, element, rawJavadoc);
} catch (Throwable t) {
return null;
}
}
if (oldJavadoc2HTML != null) {
try {
- return (String) oldJavadoc2HTML.invoke(null, member, rawJavadoc);
+ return (String) oldJavadoc2HTML.invoke(instance, member, element, rawJavadoc);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+ if (lsJavadoc2HTML != null) {
+ try {
+ return (String) lsJavadoc2HTML.invoke(instance, member, element, rawJavadoc);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+ if (reallyOldJavadoc2HTML != null) {
+ try {
+ return (String) reallyOldJavadoc2HTML.invoke(instance, member, rawJavadoc);
} catch (Throwable t) {
return null;
}
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index 62c38e5e..7ba663cc 100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2023 The Project Lombok Authors.
+ * Copyright (C) 2010-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,7 @@
*/
package lombok.launch;
-import static lombok.eclipse.EcjAugments.ASTNode_generatedBy;
+import static lombok.eclipse.EcjAugments.*;
import static lombok.eclipse.Eclipse.*;
import java.io.BufferedOutputStream;
@@ -33,6 +33,7 @@ import java.lang.reflect.Method;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Stack;
import org.eclipse.core.runtime.CoreException;
@@ -51,7 +52,9 @@ import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.FieldInfo;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
@@ -60,7 +63,9 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor;
import org.eclipse.jdt.internal.core.SourceField;
+import org.eclipse.jdt.internal.core.SourceFieldElementInfo;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.TokenScanner;
@@ -69,6 +74,7 @@ import org.eclipse.jdt.internal.corext.refactoring.code.CallContext;
import org.eclipse.jdt.internal.corext.refactoring.code.SourceProvider;
import org.eclipse.jdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment;
+import lombok.eclipse.handlers.EclipseHandlerUtil;
import lombok.permit.Permit;
/** These contain a mix of the following:
@@ -271,11 +277,16 @@ final class PatchFixesHider {
public static final class Delegate {
private static final Method HANDLE_DELEGATE_FOR_TYPE;
private static final Method ADD_GENERATED_DELEGATE_METHODS;
+ public static final Method IS_DELEGATE_SOURCE_METHOD;
+ public static final Method RETURN_ELEMENT_INFO;
static {
- Class> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegatePortal");
- HANDLE_DELEGATE_FOR_TYPE = Util.findMethod(shadowed, "handleDelegateForType", Object.class);
- ADD_GENERATED_DELEGATE_METHODS = Util.findMethod(shadowed, "addGeneratedDelegateMethods", Object.class, Object.class);
+ Class> shadowedPortal = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegatePortal");
+ HANDLE_DELEGATE_FOR_TYPE = Util.findMethod(shadowedPortal, "handleDelegateForType", Object.class);
+ ADD_GENERATED_DELEGATE_METHODS = Util.findMethod(shadowedPortal, "addGeneratedDelegateMethods", Object.class, Object.class);
+ Class> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchDelegate");
+ IS_DELEGATE_SOURCE_METHOD = Util.findMethod(shadowed, "isDelegateSourceMethod", Object.class);
+ RETURN_ELEMENT_INFO = Util.findMethod(shadowed, "returnElementInfo", Object.class);
}
public static boolean handleDelegateForType(Object classScope) {
@@ -285,6 +296,14 @@ final class PatchFixesHider {
public static Object[] addGeneratedDelegateMethods(Object returnValue, Object javaElement) {
return (Object[]) Util.invokeMethod(ADD_GENERATED_DELEGATE_METHODS, returnValue, javaElement);
}
+
+ public static boolean isDelegateSourceMethod(Object sourceMethod) {
+ return (Boolean) Util.invokeMethod(IS_DELEGATE_SOURCE_METHOD, sourceMethod);
+ }
+
+ public static Object returnElementInfo(Object delegateSourceMethod) {
+ return Util.invokeMethod(RETURN_ELEMENT_INFO, delegateSourceMethod);
+ }
}
/** Contains patch code to support {@code val} (eclipse specific) */
@@ -426,20 +445,18 @@ final class PatchFixesHider {
/** Contains patch code to support Javadoc for generated methods */
public static final class Javadoc {
private static final Method GET_HTML;
- private static final Method PRINT_METHOD;
static {
Class> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc");
- GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class);
- PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class);
+ GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", Object.class, String.class, Object.class);
}
public static String getHTMLContentFromSource(String original, IJavaElement member) {
- return (String) Util.invokeMethod(GET_HTML, original, member);
+ return (String) Util.invokeMethod(GET_HTML, null, original, member);
}
- public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
- return (StringBuffer) Util.invokeMethod(PRINT_METHOD, methodDeclaration, tab, output, type);
+ public static String getHTMLContentFromSource(String original, Object instance, IJavaElement member) {
+ return (String) Util.invokeMethod(GET_HTML, instance, original, member);
}
}
@@ -928,7 +945,99 @@ final class PatchFixesHider {
}
}
+ public static class FieldInitializer {
+ public static final Field INFO_STACK;
+ public static final Field FIELD_INFO;
+ public static final Field SOURCE_FIELD_ELEMENT_INFO;
+ public static final Field INITIALIZATION_SOURCE;
+ public static final Field NODE;
+ public static final boolean INITIALIZED;
+
+ static {
+ INFO_STACK = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "infoStack");
+ FIELD_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$fieldInfo");
+ SOURCE_FIELD_ELEMENT_INFO = Permit.permissiveGetField(CompilationUnitStructureRequestor.class, "$sourceFieldElementInfo");
+ INITIALIZATION_SOURCE = Permit.permissiveGetField(SourceFieldElementInfo.class, "initializationSource");
+ NODE = Permit.permissiveGetField(FieldInfo.class, "node");
+ INITIALIZED = INFO_STACK != null && FIELD_INFO != null && SOURCE_FIELD_ELEMENT_INFO != null && INITIALIZATION_SOURCE != null && NODE != null;
+ }
+
+ public static boolean storeFieldInfo(CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
+ try {
+ if (INITIALIZED) {
+ Stack> infoStack = Permit.get(INFO_STACK, compilationUnitStructureRequestor);
+ Object fieldInfo = infoStack.peek();
+ Permit.set(FIELD_INFO, compilationUnitStructureRequestor, fieldInfo);
+ }
+ } catch (Exception e) {
+ // do not break eclipse
+ }
+ return false;
+ }
+ public static void storeSourceFieldElementInfo(SourceFieldElementInfo fieldInfo, CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
+ try {
+ if (INITIALIZED) {
+ Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, fieldInfo);
+ }
+ } catch (Exception e) {
+ // do not break eclipse
+ }
+ }
+
+ public static void overwriteInitializer(CompilationUnitStructureRequestor compilationUnitStructureRequestor) {
+ try {
+ if (INITIALIZED) {
+ FieldInfo fieldInfo = Permit.get(FIELD_INFO, compilationUnitStructureRequestor);
+ Permit.set(FIELD_INFO, compilationUnitStructureRequestor, null);
+
+ SourceFieldElementInfo sourceFieldElementInfo = Permit.get(SOURCE_FIELD_ELEMENT_INFO,compilationUnitStructureRequestor);
+ Permit.set(SOURCE_FIELD_ELEMENT_INFO, compilationUnitStructureRequestor, null);
+
+ if (sourceFieldElementInfo.getInitializationSource() != null) {
+ AbstractVariableDeclaration node = Permit.get(NODE, fieldInfo);
+
+ if (PatchFixes.isGenerated(node)) {
+ Permit.set(INITIALIZATION_SOURCE, sourceFieldElementInfo, node.initialization.toString().toCharArray());
+ }
+ }
+ }
+ } catch (Exception e) {
+ // do not break eclipse
+ }
+ }
+ }
+
public static class Tests {
+ public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
+ return (StringBuffer) printMethod(methodDeclaration, tab, (Object) output, type);
+ }
+
+ public static StringBuilder printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuilder output, TypeDeclaration type) {
+ return (StringBuilder) printMethod(methodDeclaration, tab, (Object) output, type);
+ }
+
+ public static Object printMethod(AbstractMethodDeclaration methodDeclaration, int tab, Object output, TypeDeclaration type) {
+ Map docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit);
+ Method printIndent = Permit.permissiveGetMethod(org.eclipse.jdt.internal.compiler.ast.ASTNode.class, "printIndent", int.class, output.getClass());
+ if (docs != null) {
+ String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration);
+ String rawJavadoc = docs.get(signature);
+ if (rawJavadoc != null) {
+ for (String line : rawJavadoc.split("\r?\n")) {
+ try {
+ Appendable sb = (Appendable) Permit.invoke(printIndent, null, tab, output);
+ sb.append(line).append("\n");
+ } catch (Throwable e) {
+ // Ignore
+ }
+ }
+ }
+ }
+ Method printMethodDeclaration = Permit.permissiveGetMethod(AbstractMethodDeclaration.class, "print", int.class, output.getClass());
+ Permit.invokeSneaky(printMethodDeclaration, methodDeclaration, tab, output);
+ return output;
+ }
+
public static Object getBundle(Object original, Class> c) {
if (original != null) {
return original;
@@ -958,5 +1067,9 @@ final class PatchFixesHider {
public static StringBuffer returnStringBuffer(Object p1, StringBuffer buffer) {
return buffer;
}
+
+ public static StringBuilder returnStringBuilder(Object p1, StringBuilder buffer) {
+ return buffer;
+ }
}
}
diff --git a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java
index 2ff6839e..0e8d5895 100644
--- a/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java
+++ b/src/support/lombok/eclipse/dependencies/DownloadEclipseDependencies.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.dependencies;
import java.io.BufferedInputStream;
@@ -7,71 +28,57 @@ import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.List;
+import java.util.Set;
/**
* Download eclipse bundles.
*/
public class DownloadEclipseDependencies {
- public static void main(String[] args) throws IOException {
+ public static void main(String[] args) throws Exception {
String target = args[0];
String eclipseVersion = args[1];
- String updatePage = args[2];
- String[] packages = Arrays.copyOfRange(args, 3, args.length);
+ String updateSiteUrl = args[2];
+ boolean resolveDependencies = Boolean.parseBoolean(args[3]);
+ List bundles = Arrays.asList(Arrays.copyOfRange(args, 4, args.length));
+
+ UpdateSite updateSite = new UpdateSite();
+ updateSite.read(updateSiteUrl);
+
+ final Set artifacts;
+ if (resolveDependencies) {
+ artifacts = updateSite.resolveWithDependencies(bundles);
+ } else {
+ artifacts = updateSite.resolveWithoutDependencies(bundles);
+ }
String pluginTarget = target + "/" + eclipseVersion + "/plugins/";
+ String pluginSource = updateSite.getResolvedUrl() + "/plugins/";
- String indexData = readUrlAsString(updatePage);
-
- for (String pkg : packages) {
- Matcher matcher = Pattern.compile("(" + pkg.replace(".", "\\.") + "_.*?\\.jar)").matcher(indexData);
- if (matcher.find()) {
- String path = matcher.group(1);
-
- try {
- downloadFile(path, updatePage, pluginTarget);
- } catch (Exception e) {
- }
-
- int index = path.lastIndexOf("_");
- String source = path.substring(0, index) + ".source" + path.substring(index);
- if (indexData.contains(source)) {
- try {
- downloadFile(source, updatePage, pluginTarget);
- } catch (Exception e) {
- }
- }
- } else {
- System.out.println("Bundle \"" + pkg + "\" not found");
+ for (String artifact : artifacts) {
+ try {
+ downloadFile(artifact, pluginSource, pluginTarget);
+ } catch (Exception e) {
+ }
+
+ int index = artifact.lastIndexOf("_");
+ String source = artifact.substring(0, index) + ".source" + artifact.substring(index);
+ try {
+ downloadFile(source, pluginSource, pluginTarget);
+ } catch (Exception e) {
}
}
writeEclipseLibrary(target, eclipseVersion);
}
- private static String readUrlAsString(String url) throws MalformedURLException, IOException {
- InputStream in = getStreamForUrl(url);
-
- StringBuilder sb = new StringBuilder();
-
- int bufferSize = 1024;
- char[] buffer = new char[bufferSize];
- InputStreamReader reader = new InputStreamReader(in, "UTF-8");
- for (int count = 0; (count = reader.read(buffer, 0, bufferSize)) > 0;) {
- sb.append(buffer, 0, count);
- }
- return sb.toString();
- }
-
private static void downloadFile(String filename, String repositoryUrl, String target) throws IOException {
new File(target).mkdirs();
File targetFile = new File(target, filename);
@@ -87,10 +94,13 @@ public class DownloadEclipseDependencies {
out = new FileOutputStream(targetFile);
copy(in, out);
System.out.println("[done]");
- } catch(IOException e) {
+ } catch (IOException e) {
System.out.println("[error]");
} finally {
- if (in != null) try { in.close(); } catch (Exception ignore) {}
+ if (in != null) try {
+ in.close();
+ } catch (Exception ignore) {
+ }
if (out != null) out.close();
}
}
@@ -111,7 +121,7 @@ public class DownloadEclipseDependencies {
InputStream in = new BufferedInputStream(connection.getInputStream());
return in;
}
-
+
private static void writeEclipseLibrary(String target, String eclipseVersion) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("\n");
@@ -121,7 +131,8 @@ public class DownloadEclipseDependencies {
sb.append("\" systemlibrary=\"false\">\n");
File[] files = new File(new File(target, eclipseVersion), "plugins").listFiles(new FilenameFilter() {
- @Override public boolean accept(File dir, String name) {
+ @Override
+ public boolean accept(File dir, String name) {
return name.endsWith(".jar") && !name.contains(".source_");
}
});
diff --git a/src/support/lombok/eclipse/dependencies/UpdateSite.java b/src/support/lombok/eclipse/dependencies/UpdateSite.java
new file mode 100644
index 00000000..40524568
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/UpdateSite.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayDeque;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXSource;
+
+import org.xml.sax.InputSource;
+
+import lombok.eclipse.dependencies.model.Child;
+import lombok.eclipse.dependencies.model.Repository;
+import lombok.eclipse.dependencies.model.Required;
+import lombok.eclipse.dependencies.model.Unit;
+import lombok.eclipse.dependencies.model.VersionRange;
+
+public class UpdateSite {
+ private static final String OS_NAME = System.getProperty("os.name").toLowerCase();
+ private static final String OSGI_OS = OS_NAME.contains("windows") ? "windows" : OS_NAME.contains("mac") ? "mac" : "linux";
+ private static final String OS_ARCH = System.getProperty("os.arch");
+ private static final String OSGI_ARCH = OS_ARCH.equals("aarch64") ? "aarch64" : "x86_64";
+
+ private JAXBContext jaxbContext;
+ private Repository repository;
+ private String resolvedUrl;
+ private SAXParserFactory saxParserFactory;
+
+ public UpdateSite() throws Exception {
+ jaxbContext = JAXBContext.newInstance(Repository.class);
+
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ spf.setXIncludeAware(false);
+ saxParserFactory = spf;
+ }
+
+ public void read(String url) throws Exception {
+ String currentUrl = url;
+ try {
+ while (true) {
+ String child = resolveNextChild(currentUrl);
+ if (child.startsWith("https://")) {
+ currentUrl = child;
+ } else {
+ currentUrl += child;
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // Found the real repository
+ }
+
+ resolvedUrl = currentUrl;
+
+ try (InputStream inputStream = readJarOrXml(resolvedUrl, "content")) {
+ repository = unmarshalRepository(inputStream);
+ }
+ }
+
+ public Set resolveWithoutDependencies(List dependencies) {
+ return resolve(dependencies, false);
+ }
+
+ public Set resolveWithDependencies(List dependencies) {
+ return resolve(dependencies, true);
+ }
+
+ private Set resolve(List dependencies, boolean withDependencies) {
+ Queue toResolve = new ArrayDeque<>();
+ for (String dependency : dependencies) {
+ String[] split = dependency.split(":");
+ Required required = new Required();
+ required.namespace = split[0];
+ required.name = split[1];
+ required.range = VersionRange.ALL;
+ toResolve.add(required);
+ }
+ Set resolved = new HashSet<>();
+ while (!toResolve.isEmpty()) {
+ Required next = toResolve.poll();
+
+ // Skip already resolved
+ if (resolved.stream().anyMatch(u -> u.satisfies(next))) {
+ continue;
+ }
+
+ List satisfyingUnits = repository.units.stream().filter(u -> u.satisfies(next)).collect(Collectors.toList());
+ // Skip unknown
+ if (satisfyingUnits.isEmpty()) {
+ System.out.println("Skipping unknown unit " + next);
+ continue;
+ }
+
+ // Skip JDK dependencies
+ boolean jdkDependency = satisfyingUnits.stream().anyMatch(u -> u.id.equals("a.jre.javase"));
+ if (jdkDependency) {
+ continue;
+ }
+
+ if (satisfyingUnits.size() > 1) {
+ System.out.println("Ambiguous resolution for " + next + ": " + satisfyingUnits.toString() + ", picking first");
+ }
+
+ Unit unit = satisfyingUnits.get(0);
+ resolved.add(unit);
+
+ if (withDependencies && unit.requires != null) {
+ for (Required required : unit.requires) {
+ if (required.optional) continue;
+ if (!matchesFilter(required.filter)) continue;
+
+ toResolve.add(required);
+ }
+ }
+ }
+
+ return resolved.stream().map(u -> u.toString() + ".jar").collect(Collectors.toSet());
+ }
+
+ // Dummy implementation
+ private boolean matchesFilter(String filter) {
+ if (filter == null) {
+ return true;
+ }
+ if (filter.contains("osgi.arch=") && !filter.contains("osgi.arch=" + OSGI_ARCH)) {
+ return false;
+ }
+ if (filter.contains("osgi.os=") && !filter.contains("osgi.os=" + OSGI_OS)) {
+ return false;
+ }
+ return true;
+ }
+
+ private String resolveNextChild(String currentUrl) throws Exception {
+ try (InputStream inputStream = readJarOrXml(currentUrl, "compositeContent")) {
+ Repository repository = unmarshalRepository(inputStream);
+ Child lastChild = repository.children.get(repository.children.size() - 1);
+ return lastChild.location;
+ }
+ }
+
+ private Repository unmarshalRepository(InputStream inputStream) throws Exception {
+ Source source = new SAXSource(saxParserFactory.newSAXParser().getXMLReader(), new InputSource(inputStream));
+ Repository repository = (Repository) jaxbContext.createUnmarshaller().unmarshal(source);
+ return repository;
+ }
+
+ private InputStream readJarOrXml(String url, String name) throws Exception {
+ try {
+ return getStreamForUrl(url + "/" + name + ".xml");
+ } catch (FileNotFoundException e) {
+ System.out.println("Not found, trying jar");
+ }
+ ZipInputStream zipInputStream = new ZipInputStream(getStreamForUrl(url + "/" + name + ".jar"));
+ ZipEntry entry;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ if (entry.getName().equals(name + ".xml")) {
+ return zipInputStream;
+ }
+ }
+ throw new FileNotFoundException();
+ }
+
+ private static InputStream getStreamForUrl(String url) throws Exception {
+ System.out.println("Reading " + url);
+ HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+ connection.setRequestProperty("User-Agent", "lombok");
+ connection.setRequestProperty("Accept", "*/*");
+ InputStream in = new BufferedInputStream(connection.getInputStream());
+ return in;
+ }
+
+ public String getResolvedUrl() {
+ return resolvedUrl;
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/Child.java b/src/support/lombok/eclipse/dependencies/model/Child.java
new file mode 100644
index 00000000..1aedc77f
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Child.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import javax.xml.bind.annotation.XmlAttribute;
+
+public class Child {
+ @XmlAttribute
+ public String location;
+}
\ No newline at end of file
diff --git a/src/support/lombok/eclipse/dependencies/model/Provided.java b/src/support/lombok/eclipse/dependencies/model/Provided.java
new file mode 100644
index 00000000..29762f8c
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Provided.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+public class Provided {
+ @XmlAttribute
+ public String namespace;
+ @XmlAttribute
+ public String name;
+ @XmlAttribute
+ @XmlJavaTypeAdapter(VersionAdapter.class)
+ public Version version;
+
+ @Override
+ public String toString() {
+ return namespace + ":" + name + "_" + version;
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/Repository.java b/src/support/lombok/eclipse/dependencies/model/Repository.java
new file mode 100644
index 00000000..17c1b236
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Repository.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Repository {
+ @XmlElementWrapper(name = "children")
+ @XmlElement(name="child")
+ public List children;
+
+ @XmlElementWrapper(name = "units")
+ @XmlElement(name="unit")
+ public List units;
+}
\ No newline at end of file
diff --git a/src/support/lombok/eclipse/dependencies/model/Required.java b/src/support/lombok/eclipse/dependencies/model/Required.java
new file mode 100644
index 00000000..0d5ae2d0
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Required.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+public class Required {
+ @XmlAttribute
+ public String namespace;
+ @XmlAttribute
+ public String name;
+ @XmlAttribute
+ @XmlJavaTypeAdapter(VersionRangeAdapter.class)
+ public VersionRange range;
+ @XmlAttribute
+ public boolean optional;
+ @XmlElement
+ public String filter;
+
+ @Override
+ public String toString() {
+ return namespace + ":" + name + "_" + range;
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/Unit.java b/src/support/lombok/eclipse/dependencies/model/Unit.java
new file mode 100644
index 00000000..781651ec
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Unit.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+public class Unit {
+ @XmlAttribute
+ public String id;
+ @XmlAttribute
+ @XmlJavaTypeAdapter(VersionAdapter.class)
+ public Version version;
+
+ @XmlElementWrapper(name = "provides")
+ @XmlElement(name="provided")
+ public List provides;
+
+ @XmlElementWrapper(name = "requires")
+ @XmlElement(name="required")
+ public List requires;
+
+ public boolean satisfies(Required required) {
+ return provides.stream().anyMatch(p -> p.namespace.equals(required.namespace) && p.name.equals(required.name) && required.range.contains(p.version));
+ }
+
+ @Override
+ public String toString() {
+ return id + "_" + version;
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/Version.java b/src/support/lombok/eclipse/dependencies/model/Version.java
new file mode 100644
index 00000000..0ebcf2ef
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/Version.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+public class Version {
+ private int major;
+ private int minor;
+ private int micro;
+ private String qualifier = "";
+
+ public static Version parse(String v) {
+ String[] parts = v.split("\\.", 4);
+
+ Version version = new Version();
+ version.major = Integer.parseInt(parts[0]);
+ if (parts.length > 1) {
+ version.minor = Integer.parseInt(parts[1]);
+ }
+ if (parts.length > 2) {
+ version.micro = Integer.parseInt(parts[2]);
+ }
+ if (parts.length > 3) {
+ version.qualifier = parts[3];
+ }
+ return version;
+ }
+
+ public int compareTo(Version other) {
+ int result = major - other.major;
+ if (result != 0) return result;
+
+ result = minor - other.minor;
+ if (result != 0) return result;
+
+ result = micro - other.micro;
+ if (result != 0) return result;
+
+ return qualifier.compareTo(other.qualifier);
+ }
+
+ @Override
+ public String toString() {
+ String result = major + "." + minor + "." + micro;
+ if (!qualifier.isEmpty()) result += "." + qualifier;
+ return result;
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java b/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java
new file mode 100644
index 00000000..3c0f0ca1
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/VersionAdapter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class VersionAdapter extends XmlAdapter {
+
+ @Override
+ public Version unmarshal(String v) throws Exception {
+ return Version.parse(v);
+ }
+
+ @Override
+ public String marshal(Version v) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/VersionRange.java b/src/support/lombok/eclipse/dependencies/model/VersionRange.java
new file mode 100644
index 00000000..7dda2dce
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/VersionRange.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+public class VersionRange {
+ public static final VersionRange ALL = VersionRange.parse("0.0.0");
+
+ private Version min;
+ private Version max;
+ private boolean leftInclusive;
+ private boolean leftExclusive;
+ private boolean rightInclusive;
+ private boolean rightExclusive;
+
+ public static VersionRange parse(String v) {
+ VersionRange versionRange = new VersionRange();
+ versionRange.leftInclusive = v.startsWith("[");
+ versionRange.leftExclusive = v.startsWith("(");
+ versionRange.rightInclusive = v.endsWith("]");
+ versionRange.rightExclusive = v.endsWith(")");
+
+ if (!versionRange.leftInclusive && !versionRange.leftExclusive) {
+ Version version = Version.parse(v);
+ versionRange.min = version;
+ versionRange.leftInclusive = true;
+ return versionRange;
+ }
+
+ String[] parts = v.replaceAll("[\\[\\(\\)\\]]", "").split(",");
+ versionRange.min = Version.parse(parts[0]);
+ versionRange.max = Version.parse(parts[1]);
+ return versionRange;
+ }
+
+ public boolean contains(Version version) {
+ if (min != null) {
+ int result = min.compareTo(version);
+ if (result > 0) return false;
+ if (result == 0 && !leftInclusive) return false;
+ }
+ if (max != null) {
+ int result = max.compareTo(version);
+ if (result < 0) return false;
+ if (result == 0 && !rightInclusive) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (leftInclusive) sb.append("[");
+ if (leftExclusive) sb.append("(");
+ if (min != null) sb.append(min);
+ sb.append(",");
+ if (max != null) sb.append(max);
+ if (rightInclusive) sb.append("]");
+ if (rightExclusive) sb.append(")");
+ return sb.toString();
+ }
+}
diff --git a/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java b/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java
new file mode 100644
index 00000000..43331817
--- /dev/null
+++ b/src/support/lombok/eclipse/dependencies/model/VersionRangeAdapter.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.dependencies.model;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class VersionRangeAdapter extends XmlAdapter {
+
+ @Override
+ public VersionRange unmarshal(String v) throws Exception {
+ return VersionRange.parse(v);
+ }
+
+ @Override
+ public String marshal(VersionRange v) throws Exception {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/test/bytecode/resource/PostCompilePreventNullAnalysis.java b/test/bytecode/resource/PostCompilePreventNullAnalysis.java
new file mode 100644
index 00000000..0c9b387b
--- /dev/null
+++ b/test/bytecode/resource/PostCompilePreventNullAnalysis.java
@@ -0,0 +1,15 @@
+public class PostCompilePreventNullAnalysis {
+ public void test() {
+ Object o = "Hello World!";
+ try {
+ System.out.println(o);
+ } finally {
+ if (o != null) {
+ if (lombok.Lombok.preventNullAnalysis(o) != null) {
+ o.toString();
+ }
+ }
+ }
+ }
+
+}
diff --git a/test/bytecode/src/lombok/bytecode/TestPostCompiler.java b/test/bytecode/src/lombok/bytecode/TestPostCompiler.java
index 2704ecec..3814e00d 100644
--- a/test/bytecode/src/lombok/bytecode/TestPostCompiler.java
+++ b/test/bytecode/src/lombok/bytecode/TestPostCompiler.java
@@ -33,7 +33,7 @@ import org.junit.Test;
public class TestPostCompiler {
@Test
- public void testPostCompiler() throws IOException {
+ public void testPostCompilerSneakyThrows() {
byte[] compiled = TestClassFileMetaData.compile(new File("test/bytecode/resource/PostCompileSneaky.java"));
DiagnosticsReceiver receiver = new DiagnosticsReceiver() {
@Override public void addWarning(String message) {
@@ -50,5 +50,31 @@ public class TestPostCompiler {
assertNotSame("Post-compiler did not do anything; we expected it to remove a Lombok.sneakyThrow() call.", compiled, transformed);
assertTrue("After removing a sneakyThrow the classfile got... bigger (or stayed equal in size). Huh?", transformed.length < compiled.length);
+
+ assertFalse("After post compilation, expected no lombok.Lombok.sneakyThrow() call in compiled code, but it's there",
+ new ClassFileMetaData(transformed).usesMethod("lombok/Lombok", "sneakyThrow"));
+ }
+
+ @Test
+ public void testPostCompilerPreventNullAnalysis() {
+ byte[] compiled = TestClassFileMetaData.compile(new File("test/bytecode/resource/PostCompilePreventNullAnalysis.java"));
+ DiagnosticsReceiver receiver = new DiagnosticsReceiver() {
+ @Override public void addWarning(String message) {
+ fail("Warning during post compilation processing of a sneakyThrow call: " + message);
+ }
+
+ @Override public void addError(String message) {
+ fail("Error during post compilation processing of a sneakyThrow call: " + message);
+ }
+ };
+ assertTrue("Before post compilation, expected lombok.Lombok.preventNullAnalysis() call in compiled code, but it's not there",
+ new ClassFileMetaData(compiled).usesMethod("lombok/Lombok", "preventNullAnalysis"));
+ byte[] transformed = PostCompiler.applyTransformations(compiled, "PostCompilePreventNullAnalysis.java", receiver);
+
+ assertNotSame("Post-compiler did not do anything; we expected it to remove a Lombok.preventNullAnalysis() call.", compiled, transformed);
+ assertTrue("After removing a sneakyThrow the classfile got... bigger (or stayed equal in size). Huh?", transformed.length < compiled.length);
+
+ assertFalse("After post compilation, expected no lombok.Lombok.preventNullAnalysis() call in compiled code, but it's there",
+ new ClassFileMetaData(transformed).usesMethod("lombok/Lombok", "preventNullAnalysis"));
}
}
diff --git a/test/core/src/lombok/AbstractRunTests.java b/test/core/src/lombok/AbstractRunTests.java
index 51ec41c5..0cb379ff 100644
--- a/test/core/src/lombok/AbstractRunTests.java
+++ b/test/core/src/lombok/AbstractRunTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,14 +29,12 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
-import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import org.junit.Assert;
@@ -83,28 +81,38 @@ public abstract class AbstractRunTests {
return new FileTester() {
@Override public void runTest() throws Throwable {
if (directiveFailure_ != null) throw directiveFailure_;
- LinkedHashSet messages = new LinkedHashSet();
- StringWriter writer = new StringWriter();
-
LombokConfiguration.overrideConfigurationResolverFactory(new ConfigurationResolverFactory() {
@Override public ConfigurationResolver createResolver(URI sourceLocation) {
return sourceDirectives_.getConfiguration();
}
});
+ TestParameters testParameters = new TestParameters();
+ testParameters.setEncoding(sourceDirectives_.getSpecifiedEncoding());
+ testParameters.setFormatPreferences(sourceDirectives_.getFormatPreferences());
+ testParameters.setMinVersion(sourceDirectives_.minVersion());
+ testParameters.setVerifyDiet(sourceDirectives_.isVerifyDiet());
boolean checkPositions = !(params instanceof TestLombokFilesIdempotent || params instanceof TestSourceFiles) && !sourceDirectives_.isSkipCompareContent();
+ testParameters.setCheckPositions(checkPositions);
+ String javaVersionString = System.getProperty("compiler.compliance.level");
+ if (javaVersionString != null) {
+ long version = Long.parseLong(javaVersionString);
+ testParameters.setSourceVersion(version);
+ testParameters.setTargetVersion(version);
+ }
- boolean changed = transformCode(messages, writer, file, sourceDirectives_.getSpecifiedEncoding(), sourceDirectives_.getFormatPreferences(), sourceDirectives_.minVersion(), checkPositions);
+ TransformationResult result = transformCode(file, testParameters);
+ boolean changed = result.isChanged();
boolean forceUnchanged = sourceDirectives_.forceUnchanged() || sourceDirectives_.isSkipCompareContent();
- if (params.expectChanges() && !forceUnchanged && !changed) messages.add(new CompilerMessage(-1, -1, true, "not flagged modified"));
- if (!params.expectChanges() && changed) messages.add(new CompilerMessage(-1, -1, true, "unexpected modification"));
+ if (params.expectChanges() && !forceUnchanged && !changed) result.addMessage(new CompilerMessage(-1, -1, true, "not flagged modified"));
+ if (!params.expectChanges() && changed) result.addMessage(new CompilerMessage(-1, -1, true, "unexpected modification"));
- compare(file.getName(), expected, writer.toString(), messages, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent());
+ compare(file.getName(), expected, result, params.printErrors(), sourceDirectives_.isSkipCompareContent() || expected.isSkipCompareContent());
}
};
}
- protected abstract boolean transformCode(Collection messages, StringWriter result, File file, String encoding, Map formatPreferences, int minVersion, boolean checkPositions) throws Throwable;
+ protected abstract TransformationResult transformCode(File file, TestParameters parameters) throws Throwable;
protected String readFile(File file) throws IOException {
BufferedReader reader;
@@ -154,7 +162,10 @@ public abstract class AbstractRunTests {
}
}
- private void compare(String name, LombokTestSource expected, String actualFile, LinkedHashSet actualMessages, boolean printErrors, boolean skipCompareContent) throws Throwable {
+ private void compare(String name, LombokTestSource expected, TransformationResult result, boolean printErrors, boolean skipCompareContent) throws Throwable {
+ String actualFile = result.getOutput();
+ LinkedHashSet actualMessages = result.getMessages();
+
if (!skipCompareContent) try {
compareContent(name, expected.getContent(), actualFile);
} catch (Throwable e) {
diff --git a/test/core/src/lombok/LombokTestSource.java b/test/core/src/lombok/LombokTestSource.java
index 27ffc31a..92bc53ea 100644
--- a/test/core/src/lombok/LombokTestSource.java
+++ b/test/core/src/lombok/LombokTestSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2019 The Project Lombok Authors.
+ * Copyright (C) 2014-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -58,6 +58,7 @@ public class LombokTestSource {
private final boolean skipCompareContent;
private final boolean skipIdempotent;
private final boolean unchanged;
+ private final boolean verifyDiet;
private final int versionLowerLimit, versionUpperLimit;
private final ConfigurationResolver configuration;
private final String specifiedEncoding;
@@ -113,6 +114,10 @@ public class LombokTestSource {
return skipIdempotent;
}
+ public boolean isVerifyDiet() {
+ return verifyDiet;
+ }
+
public String getSpecifiedEncoding() {
return specifiedEncoding;
}
@@ -162,6 +167,7 @@ public class LombokTestSource {
private static final Pattern SKIP_COMPARE_CONTENT_PATTERN = Pattern.compile("^\\s*skip[- ]?compare[- ]?contents?\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE);
private static final Pattern SKIP_IDEMPOTENT_PATTERN = Pattern.compile("^\\s*skip[- ]?idempotent\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE);
private static final Pattern ISSUE_REF_PATTERN = Pattern.compile("^\\s*issue #?\\d+(:?\\s+.*)?$", Pattern.CASE_INSENSITIVE);
+ private static final Pattern VERIFY_DIET_PATTERN = Pattern.compile("^\\s*eclipse:\\s*verify[- ]?diet\\s*(?:[-:].*)?$", Pattern.CASE_INSENSITIVE);
private LombokTestSource(File file, String content, List messages, List directives) {
this.file = file;
@@ -175,6 +181,7 @@ public class LombokTestSource {
boolean skipCompareContent = false;
boolean skipIdempotent = false;
boolean unchanged = false;
+ boolean verifyDiet = false;
String encoding = null;
Map formats = new HashMap();
String[] platformLimit = null;
@@ -204,6 +211,10 @@ public class LombokTestSource {
if (ISSUE_REF_PATTERN.matcher(directive).matches()) {
continue;
}
+ if (VERIFY_DIET_PATTERN.matcher(directive).matches()) {
+ verifyDiet = true;
+ continue;
+ }
if (lc.startsWith("platform ")) {
String platformDesc = lc.substring("platform ".length());
@@ -257,6 +268,7 @@ public class LombokTestSource {
this.skipCompareContent = skipCompareContent;
this.skipIdempotent = skipIdempotent;
this.unchanged = unchanged;
+ this.verifyDiet = verifyDiet;
this.platforms = platformLimit == null ? null : Arrays.asList(platformLimit);
ConfigurationProblemReporter reporter = new ConfigurationProblemReporter() {
diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java
index adfb1fce..918a0de4 100644
--- a/test/core/src/lombok/RunTestsViaDelombok.java
+++ b/test/core/src/lombok/RunTestsViaDelombok.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2021 The Project Lombok Authors.
+ * Copyright (C) 2009-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -66,24 +66,24 @@ import com.sun.tools.javac.tree.TreeScanner;
import lombok.delombok.Delombok;
import lombok.javac.CapturingDiagnosticListener;
-import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
import lombok.javac.Javac;
public class RunTestsViaDelombok extends AbstractRunTests {
private Delombok delombok = new Delombok();
@Override
- public boolean transformCode(Collection messages, StringWriter result, final File file, String encoding, Map formatPreferences, int version, boolean checkPositions) throws Throwable {
+ public TransformationResult transformCode(final File file, TestParameters parameters) throws Throwable {
+ TransformationResult result = new TransformationResult();
delombok.setVerbose(true);
ChangedChecker cc = new ChangedChecker();
delombok.setFeedback(cc.feedback);
delombok.setForceProcess(true);
- delombok.setCharset(encoding == null ? "UTF-8" : encoding);
- delombok.setFormatPreferences(formatPreferences);
+ delombok.setCharset(parameters.getEncoding() == null ? "UTF-8" : parameters.getEncoding());
+ delombok.setFormatPreferences(parameters.getFormatPreferences());
- delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, messages));
+ delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, result.getMessages()));
- if (checkPositions) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(version));
+ if (parameters.isCheckPositions()) delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor(parameters.getMinVersion()));
delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor());
delombok.addAdditionalAnnotationProcessor(new ValidateNoDuplicateTreeNodeProcessor());
@@ -91,12 +91,15 @@ public class RunTestsViaDelombok extends AbstractRunTests {
delombok.setSourcepath(file.getAbsoluteFile().getParent());
String bcp = System.getProperty("delombok.bootclasspath");
if (bcp != null) delombok.setBootclasspath(bcp);
- delombok.setWriter(result);
+ StringWriter sw = new StringWriter();
+ delombok.setWriter(sw);
Locale originalLocale = Locale.getDefault();
try {
Locale.setDefault(Locale.ENGLISH);
delombok.delombok();
- return cc.isChanged();
+ result.setOutput(sw.toString());
+ result.setChanged(cc.isChanged());
+ return result;
} finally {
Locale.setDefault(originalLocale);
}
diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java
index d46a890f..352ba4e6 100644
--- a/test/core/src/lombok/RunTestsViaEcj.java
+++ b/test/core/src/lombok/RunTestsViaEcj.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2021 The Project Lombok Authors.
+ * Copyright (C) 2010-2024 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -22,9 +22,7 @@
package lombok;
import java.io.File;
-import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -32,9 +30,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
-import lombok.eclipse.Eclipse;
-import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
-
import org.eclipse.core.internal.registry.ExtensionRegistry;
import org.eclipse.core.internal.runtime.Activator;
import org.eclipse.core.internal.runtime.PlatformActivator;
@@ -57,22 +52,24 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import lombok.eclipse.Eclipse;
+import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
+
public class RunTestsViaEcj extends AbstractRunTests {
- protected CompilerOptions ecjCompilerOptions() {
+ protected CompilerOptions ecjCompilerOptions(TestParameters parameters) {
CompilerOptions options = new CompilerOptions();
Map warnings = new HashMap();
- String javaVersionString = System.getProperty("compiler.compliance.level");
long ecjCompilerVersionConstant = Eclipse.getLatestEcjCompilerVersionConstant();
long ecjCompilerVersion = Eclipse.getEcjCompilerVersion();
- if (javaVersionString != null) {
- long javaVersion = Long.parseLong(javaVersionString);
- ecjCompilerVersionConstant = (javaVersion + 44) << 16;
- ecjCompilerVersion = javaVersion;
+ if (parameters.getSourceVersion() != null) {
+ ecjCompilerVersionConstant = (parameters.getSourceVersion() + 44) << 16;
+ ecjCompilerVersion = parameters.getSourceVersion();
} else {
// Preview features are only allowed if the maximum compiler version is equal to the source version
warnings.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled");
@@ -127,7 +124,8 @@ public class RunTestsViaEcj extends AbstractRunTests {
}
@Override
- public boolean transformCode(Collection messages, StringWriter result, File file, String encoding, Map formatPreferences, int minVersion, boolean checkPositions) throws Throwable {
+ public TransformationResult transformCode(File file, final TestParameters parameters) throws Throwable {
+ final TransformationResult result = new TransformationResult();
final AtomicReference compilationResult_ = new AtomicReference();
final AtomicReference compilationUnit_ = new AtomicReference();
ICompilerRequestor bitbucketRequestor = new ICompilerRequestor() {
@@ -143,12 +141,18 @@ public class RunTestsViaEcj extends AbstractRunTests {
sourceUnit = getSourceUnit(file, source);
} catch (Throwable t) {
t.printStackTrace();
- return false;
+ result.setChanged(false);
+ return result;
}
- Compiler ecjCompiler = new Compiler(createFileSystem(file, minVersion), ecjErrorHandlingPolicy(), ecjCompilerOptions(), bitbucketRequestor, new DefaultProblemFactory(Locale.ENGLISH)) {
+ Compiler ecjCompiler = new Compiler(createFileSystem(file), ecjErrorHandlingPolicy(), ecjCompilerOptions(parameters), bitbucketRequestor, new DefaultProblemFactory(Locale.ENGLISH)) {
@Override protected synchronized void addCompilationUnit(ICompilationUnit inUnit, CompilationUnitDeclaration parsedUnit) {
- if (inUnit == sourceUnit) compilationUnit_.set(parsedUnit);
+ if (inUnit == sourceUnit) {
+ compilationUnit_.set(parsedUnit);
+ if (parameters.isVerifyDiet()) {
+ result.setOutput(parsedUnit.toString());
+ }
+ }
super.addCompilationUnit(inUnit, parsedUnit);
}
};
@@ -161,24 +165,28 @@ public class RunTestsViaEcj extends AbstractRunTests {
CategorizedProblem[] problems = compilationResult.getAllProblems();
if (problems != null) for (CategorizedProblem p : problems) {
- messages.add(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.isError(), p.getMessage()));
+ result.addMessage(new CompilerMessage(p.getSourceLineNumber(), p.getSourceStart(), p.isError(), p.getMessage()));
}
CompilationUnitDeclaration cud = compilationUnit_.get();
- if (cud == null) result.append("---- No CompilationUnit provided by ecj ----");
- else {
- String output = cud.toString();
- // starting somewhere around ecj16, the print code is a bit too cavalier with printing modifiers.
- output = output.replace("non-sealed @val", "@val");
- result.append(output);
+ if (cud == null) {
+ result.setOutput("---- No CompilationUnit provided by ecj ----");
+ } else {
+ if (!parameters.isVerifyDiet()) {
+ String output = cud.toString();
+ // starting somewhere around ecj16, the print code is a bit too cavalier with printing modifiers.
+ output = output.replace("non-sealed @val", "@val");
+ result.setOutput(output);
+ }
+
+ if (eclipseAvailable()) {
+ EclipseDomConversion.toDomAst(cud, sourceArray);
+ }
}
- if (eclipseAvailable()) {
- EclipseDomConversion.toDomAst(cud, sourceArray);
- }
-
- return true;
+ result.setChanged(true);
+ return result;
}
@SuppressWarnings("unused")
@@ -238,7 +246,7 @@ public class RunTestsViaEcj extends AbstractRunTests {
}
}
- private FileSystem createFileSystem(File file, int minVersion) {
+ private FileSystem createFileSystem(File file) {
List classpath = new ArrayList();
if (new File("bin/main").exists()) classpath.add("bin/main");
classpath.add("dist/lombok.jar");
@@ -301,7 +309,7 @@ public class RunTestsViaEcj extends AbstractRunTests {
private final char[] mainTypeName;
private TestCompilationUnitEclipse(String name, String source) {
- super(null, name, null);
+ super(null, name, DefaultWorkingCopyOwner.PRIMARY);
this.source = source.toCharArray();
char[] fileNameCharArray = getFileName();
@@ -313,14 +321,6 @@ public class RunTestsViaEcj extends AbstractRunTests {
mainTypeName = CharOperation.subarray(fileNameCharArray, start, end);
}
- @Override public int hashCode() {
- return System.identityHashCode(this);
- }
-
- @Override public boolean equals(Object obj) {
- return this == obj;
- }
-
@Override public char[] getContents() {
return source;
}
diff --git a/test/core/src/lombok/TestParameters.java b/test/core/src/lombok/TestParameters.java
new file mode 100644
index 00000000..dba7b990
--- /dev/null
+++ b/test/core/src/lombok/TestParameters.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok;
+
+import java.util.Map;
+
+public class TestParameters {
+ private Long sourceVersion;
+ private Long targetVersion;
+
+ // Javac only
+ private Integer minVersion;
+ private String encoding;
+ private Map formatPreferences;
+ private boolean checkPositions;
+
+ // Eclipse/Ecj only
+ private boolean verifyDiet;
+
+ public Long getSourceVersion() {
+ return sourceVersion;
+ }
+
+ public void setSourceVersion(Long sourceVersion) {
+ this.sourceVersion = sourceVersion;
+ }
+
+ public Long getTargetVersion() {
+ return targetVersion;
+ }
+
+ public void setTargetVersion(Long targetVersion) {
+ this.targetVersion = targetVersion;
+ }
+
+ public Integer getMinVersion() {
+ return minVersion;
+ }
+
+ public void setMinVersion(Integer minVersion) {
+ this.minVersion = minVersion;
+ }
+
+ public String getEncoding() {
+ return encoding;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ public Map getFormatPreferences() {
+ return formatPreferences;
+ }
+
+ public void setFormatPreferences(Map formatPreferences) {
+ this.formatPreferences = formatPreferences;
+ }
+
+ public boolean isCheckPositions() {
+ return checkPositions;
+ }
+
+ public void setCheckPositions(boolean checkPositions) {
+ this.checkPositions = checkPositions;
+ }
+
+ public boolean isVerifyDiet() {
+ return verifyDiet;
+ }
+
+ public void setVerifyDiet(boolean verifyDiet) {
+ this.verifyDiet = verifyDiet;
+ }
+}
diff --git a/test/core/src/lombok/TransformationResult.java b/test/core/src/lombok/TransformationResult.java
new file mode 100644
index 00000000..b0d45e44
--- /dev/null
+++ b/test/core/src/lombok/TransformationResult.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok;
+
+import java.util.LinkedHashSet;
+
+import lombok.javac.CapturingDiagnosticListener.CompilerMessage;
+
+public class TransformationResult {
+ private boolean changed;
+ private boolean success;
+ private LinkedHashSet messages = new LinkedHashSet();
+ private String output;
+
+ public void addMessage(CompilerMessage message) {
+ getMessages().add(message);
+ }
+
+ public void setOutput(String output) {
+ this.output = output;
+ }
+
+ public String getOutput() {
+ return output;
+ }
+
+ public boolean isChanged() {
+ return changed;
+ }
+
+ public void setChanged(boolean changed) {
+ this.changed = changed;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public LinkedHashSet getMessages() {
+ return messages;
+ }
+}
diff --git a/test/eclipse/resource/delegate/model/DelegateModel.java b/test/eclipse/resource/delegate/model/DelegateModel.java
new file mode 100644
index 00000000..4c1700e9
--- /dev/null
+++ b/test/eclipse/resource/delegate/model/DelegateModel.java
@@ -0,0 +1,9 @@
+package pkg;
+
+import lombok.experimental.Delegate;
+
+public class DelegateModel {
+
+ @Delegate
+ private Runnable run;
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/javadoc/getterSetter/Javadoc.java b/test/eclipse/resource/javadoc/getterSetter/Javadoc.java
new file mode 100644
index 00000000..9f07e9e0
--- /dev/null
+++ b/test/eclipse/resource/javadoc/getterSetter/Javadoc.java
@@ -0,0 +1,25 @@
+package pkg;
+
+import lombok.Getter;
+import lombok.Setter;
+
+public class Javadoc {
+ /**
+ * Some text
+ *
+ * **SETTER**
+ * Setter section
+ * @param fieldName Hello, World3
+ * **GETTER**
+ * Getter section
+ * @return Sky is blue3
+ */
+ @Getter
+ @Setter
+ private int field;
+
+ public void usage() {
+ getField();
+ setField(0);
+ }
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java
new file mode 100644
index 00000000..e3ecb40f
--- /dev/null
+++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Annotation.java
@@ -0,0 +1,5 @@
+package pkg;
+
+public @interface Annotation {
+ String value();
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java
new file mode 100644
index 00000000..fad3811f
--- /dev/null
+++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Constants.java
@@ -0,0 +1,8 @@
+package pkg;
+
+import lombok.experimental.FieldNameConstants;
+
+@FieldNameConstants
+public class Constants {
+ String test;
+}
\ No newline at end of file
diff --git a/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java
new file mode 100644
index 00000000..5f8880ef
--- /dev/null
+++ b/test/eclipse/resource/noerrors/fieldNameConstantsInAnnotation/Usage.java
@@ -0,0 +1,5 @@
+package pkg;
+
+@Annotation(Constants.Fields.test)
+public class Usage {
+}
\ No newline at end of file
diff --git a/test/eclipse/src/lombok/eclipse/EclipseRunner.java b/test/eclipse/src/lombok/eclipse/EclipseRunner.java
index 1e1c17fe..36e98d9e 100644
--- a/test/eclipse/src/lombok/eclipse/EclipseRunner.java
+++ b/test/eclipse/src/lombok/eclipse/EclipseRunner.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import java.io.File;
diff --git a/test/eclipse/src/lombok/eclipse/EclipseTests.java b/test/eclipse/src/lombok/eclipse/EclipseTests.java
index 5fba9903..66f5d9fa 100644
--- a/test/eclipse/src/lombok/eclipse/EclipseTests.java
+++ b/test/eclipse/src/lombok/eclipse/EclipseTests.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022-2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import org.junit.runner.RunWith;
@@ -5,14 +26,17 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import lombok.eclipse.cleanup.CleanupTest;
+import lombok.eclipse.compile.NoErrorsTest;
import lombok.eclipse.edit.SelectTest;
+import lombok.eclipse.misc.DelegateTest;
+import lombok.eclipse.misc.JavadocTest;
import lombok.eclipse.refactoring.ExtractInterfaceTest;
import lombok.eclipse.refactoring.InlineTest;
import lombok.eclipse.refactoring.RenameTest;
import lombok.eclipse.references.FindReferencesTest;
@RunWith(Suite.class)
-@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class})
+@SuiteClasses({ExtractInterfaceTest.class, RenameTest.class, SelectTest.class, CleanupTest.class, FindReferencesTest.class, InlineTest.class, NoErrorsTest.class, JavadocTest.class, DelegateTest.class})
public class EclipseTests {
}
diff --git a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
index 38349d2d..2362ff11 100644
--- a/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
+++ b/test/eclipse/src/lombok/eclipse/RefactoringUtils.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import static org.junit.Assert.assertTrue;
diff --git a/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java b/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java
index 05deabde..ff51ef13 100644
--- a/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java
+++ b/test/eclipse/src/lombok/eclipse/SetupBeforeAfterTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022-2023 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import static org.junit.Assert.assertEquals;
diff --git a/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java b/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java
index 47010f0c..d4b934ce 100644
--- a/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java
+++ b/test/eclipse/src/lombok/eclipse/SetupSingleFileTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import java.io.File;
diff --git a/test/eclipse/src/lombok/eclipse/SetupTest.java b/test/eclipse/src/lombok/eclipse/SetupTest.java
index fe8d469c..d3a2f1b0 100644
--- a/test/eclipse/src/lombok/eclipse/SetupTest.java
+++ b/test/eclipse/src/lombok/eclipse/SetupTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse;
import java.io.File;
diff --git a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java
index 2d018228..76956aff 100644
--- a/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java
+++ b/test/eclipse/src/lombok/eclipse/cleanup/CleanupTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.cleanup;
import static lombok.eclipse.RefactoringUtils.performRefactoring;
diff --git a/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java
new file mode 100644
index 00000000..6d81d381
--- /dev/null
+++ b/test/eclipse/src/lombok/eclipse/compile/NoErrorsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.compile;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IProblemRequestor;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import lombok.eclipse.EclipseRunner;
+import lombok.eclipse.SetupSingleFileTest;
+
+@RunWith(EclipseRunner.class)
+public class NoErrorsTest {
+
+ @Rule
+ public SetupSingleFileTest setup = new SetupSingleFileTest();
+
+ @Test
+ public void fieldNameConstantsInAnnotation() throws Exception {
+ ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("Usage.java");
+
+ final List problems = new ArrayList();
+ final IProblemRequestor requestor = new IProblemRequestor() {
+ @Override
+ public void acceptProblem(IProblem problem) {
+ problems.add(problem);
+ }
+
+ @Override
+ public void beginReporting() {
+ problems.clear();
+ }
+
+ @Override
+ public void endReporting() {
+ }
+
+ @Override
+ public boolean isActive() {
+ return true;
+ }
+ };
+
+ WorkingCopyOwner workingCopyOwner = new WorkingCopyOwner() {
+ @Override
+ public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
+ return requestor;
+ }
+ };
+
+ ICompilationUnit workingCopy = cu.getWorkingCopy(workingCopyOwner, null);
+ try {
+ workingCopy.reconcile(ICompilationUnit.NO_AST, true, true, workingCopy.getOwner(), null);
+ } finally {
+ workingCopy.discardWorkingCopy();
+ }
+
+ System.out.println(problems);
+ assertTrue(problems.isEmpty());
+ }
+}
diff --git a/test/eclipse/src/lombok/eclipse/edit/SelectTest.java b/test/eclipse/src/lombok/eclipse/edit/SelectTest.java
index 9f348a0c..a9723618 100644
--- a/test/eclipse/src/lombok/eclipse/edit/SelectTest.java
+++ b/test/eclipse/src/lombok/eclipse/edit/SelectTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.edit;
import static org.junit.Assert.assertEquals;
diff --git a/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java b/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java
new file mode 100644
index 00000000..899dc9f9
--- /dev/null
+++ b/test/eclipse/src/lombok/eclipse/misc/DelegateTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.misc;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import lombok.eclipse.EclipseRunner;
+import lombok.eclipse.SetupSingleFileTest;
+
+@RunWith(EclipseRunner.class)
+public class DelegateTest {
+
+ @Rule
+ public SetupSingleFileTest setup = new SetupSingleFileTest();
+
+ @Test
+ public void model() throws Exception {
+ ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("DelegateModel.java");
+
+ WorkingCopyOwner workingCopyOwner = new WorkingCopyOwner() {};
+ ICompilationUnit workingCopy = cu.getWorkingCopy(workingCopyOwner, null);
+ try {
+ workingCopy.reconcile(ICompilationUnit.NO_AST, true, true, workingCopy.getOwner(), null);
+
+ assertThat(workingCopy.findPrimaryType().getMethods().length, is(not(0)));
+
+ IMethod runMethod = workingCopy.findPrimaryType().getMethods()[0];
+ assertEquals(runMethod.getElementName(), "run");
+
+ ISourceRange sourceRange = runMethod.getSourceRange();
+ assertNotNull(sourceRange);
+ assertEquals(sourceRange.getOffset(), 84);
+ assertEquals(sourceRange.getLength(), 9);
+ } finally {
+ workingCopy.discardWorkingCopy();
+ }
+ }
+}
diff --git a/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java
new file mode 100644
index 00000000..fd7a5daa
--- /dev/null
+++ b/test/eclipse/src/lombok/eclipse/misc/JavadocTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.eclipse.misc;
+
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.ui.text.javadoc.JavadocContentAccess2;
+import org.hamcrest.CoreMatchers;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import lombok.eclipse.EclipseRunner;
+import lombok.eclipse.SetupSingleFileTest;
+
+@RunWith(EclipseRunner.class)
+public class JavadocTest {
+
+ @Rule
+ public SetupSingleFileTest setup = new SetupSingleFileTest();
+
+ @Test
+ public void getterSetter() throws Exception {
+ ICompilationUnit cu = setup.getPackageFragment().getCompilationUnit("Javadoc.java");
+
+ IJavaElement getterInvocation = cu.codeSelect(306, 0)[0];
+ String getterHtmlContent = JavadocContentAccess2.getHTMLContent(getterInvocation, true);
+ assertThat(getterHtmlContent, CoreMatchers.containsString("Getter section"));
+ assertThat(getterHtmlContent, CoreMatchers.containsString("Returns:"));
+ assertThat(getterHtmlContent, CoreMatchers.containsString("Sky is blue3"));
+
+ IJavaElement setterInvocation = cu.codeSelect(320, 0)[0];
+ String setterHtmlContent = JavadocContentAccess2.getHTMLContent(setterInvocation, true);
+ assertThat(setterHtmlContent, CoreMatchers.containsString("Setter section"));
+ assertThat(setterHtmlContent, CoreMatchers.containsString("Parameters:"));
+ assertThat(setterHtmlContent, CoreMatchers.containsString("fieldName"));
+ assertThat(setterHtmlContent, CoreMatchers.containsString("Hello, World3"));
+ assertThat(setterHtmlContent, CoreMatchers.containsString("field"));
+ }
+}
diff --git a/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java b/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java
index d4c892f3..1ad64398 100644
--- a/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java
+++ b/test/eclipse/src/lombok/eclipse/refactoring/ExtractInterfaceTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.refactoring;
import static lombok.eclipse.RefactoringUtils.performRefactoring;
diff --git a/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java b/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java
index 1a3315b7..25a21d62 100644
--- a/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java
+++ b/test/eclipse/src/lombok/eclipse/refactoring/InlineTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2023 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.refactoring;
import static lombok.eclipse.RefactoringUtils.performRefactoring;
diff --git a/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java b/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java
index 8ce4874c..7f085f08 100644
--- a/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java
+++ b/test/eclipse/src/lombok/eclipse/refactoring/RenameTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2022-2023 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.refactoring;
import static lombok.eclipse.RefactoringUtils.performRefactoring;
diff --git a/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java b/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java
index a4668088..e2806ea3 100644
--- a/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java
+++ b/test/eclipse/src/lombok/eclipse/references/FindReferencesTest.java
@@ -1,3 +1,24 @@
+/*
+ * Copyright (C) 2023 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
package lombok.eclipse.references;
import static org.junit.Assert.*;
diff --git a/test/pretty/resource/after/UnnamedVariables.java b/test/pretty/resource/after/UnnamedVariables.java
new file mode 100644
index 00000000..f95b29ca
--- /dev/null
+++ b/test/pretty/resource/after/UnnamedVariables.java
@@ -0,0 +1,70 @@
+// version 22:
+import java.util.Arrays;
+import java.util.Scanner;
+import java.util.stream.Stream;
+
+record Box(T content) {
+}
+
+record Pair(T first, U second) {
+}
+
+public class UnnamedVariables {
+ void enhancedLoop() {
+ for (String _ : Arrays.asList("")) {
+ }
+ }
+
+ void initializationInForLoop() {
+ for (int i = 0, _ = Integer.MAX_VALUE; i < 10; i++) {
+ }
+ }
+
+ void assignment() {
+ var _ = 1;
+ }
+
+ void catchBlock() {
+ try {
+ } catch (Exception _) {
+ }
+ }
+
+ void tryWithResources() {
+ try (var _ = new Scanner("")) {
+ }
+ }
+
+ void lambda() {
+ Stream.of(1).forEach(_ -> {
+ });
+ }
+
+ Object switchStatement(Object o) {
+ return switch (o) {
+ case String _, Integer _ -> o;
+ case Long _ -> o;
+ default -> o;
+ };
+ }
+
+ void recordPattern(Object o) {
+ if (o instanceof Pair(Box _, Box(Integer _))) {
+ }
+ if (o instanceof Box(String _)) {
+ }
+ if (o instanceof Box(var _)) {
+ }
+ if (o instanceof Box(_)) {
+ }
+ }
+
+ Object recordPatternSwitch(Object o) {
+ return switch (o) {
+ case Box(String _), Box(Integer _) -> o;
+ case Box(Long _) -> o;
+ case Box(_) -> o;
+ default -> o;
+ };
+ }
+}
diff --git a/test/pretty/resource/before/UnnamedVariables.java b/test/pretty/resource/before/UnnamedVariables.java
new file mode 100644
index 00000000..f95b29ca
--- /dev/null
+++ b/test/pretty/resource/before/UnnamedVariables.java
@@ -0,0 +1,70 @@
+// version 22:
+import java.util.Arrays;
+import java.util.Scanner;
+import java.util.stream.Stream;
+
+record Box(T content) {
+}
+
+record Pair(T first, U second) {
+}
+
+public class UnnamedVariables {
+ void enhancedLoop() {
+ for (String _ : Arrays.asList("")) {
+ }
+ }
+
+ void initializationInForLoop() {
+ for (int i = 0, _ = Integer.MAX_VALUE; i < 10; i++) {
+ }
+ }
+
+ void assignment() {
+ var _ = 1;
+ }
+
+ void catchBlock() {
+ try {
+ } catch (Exception _) {
+ }
+ }
+
+ void tryWithResources() {
+ try (var _ = new Scanner("")) {
+ }
+ }
+
+ void lambda() {
+ Stream.of(1).forEach(_ -> {
+ });
+ }
+
+ Object switchStatement(Object o) {
+ return switch (o) {
+ case String _, Integer _ -> o;
+ case Long _ -> o;
+ default -> o;
+ };
+ }
+
+ void recordPattern(Object o) {
+ if (o instanceof Pair(Box _, Box(Integer _))) {
+ }
+ if (o instanceof Box(String _)) {
+ }
+ if (o instanceof Box(var _)) {
+ }
+ if (o instanceof Box(_)) {
+ }
+ }
+
+ Object recordPatternSwitch(Object o) {
+ return switch (o) {
+ case Box(String _), Box(Integer _) -> o;
+ case Box(Long _) -> o;
+ case Box(_) -> o;
+ default -> o;
+ };
+ }
+}
diff --git a/test/transform/resource/after-delombok/BuilderOnNestedClass.java b/test/transform/resource/after-delombok/BuilderOnNestedClass.java
new file mode 100644
index 00000000..76e69f78
--- /dev/null
+++ b/test/transform/resource/after-delombok/BuilderOnNestedClass.java
@@ -0,0 +1,49 @@
+public class BuilderOnNestedClass {
+ private T t;
+
+
+ public static class Nested {
+ private String a;
+
+ @java.lang.SuppressWarnings("all")
+ Nested(final String a) {
+ this.a = a;
+ }
+
+
+ @java.lang.SuppressWarnings("all")
+ public static class NestedBuilder {
+ @java.lang.SuppressWarnings("all")
+ private String a;
+
+ @java.lang.SuppressWarnings("all")
+ NestedBuilder() {
+ }
+
+ /**
+ * @return {@code this}.
+ */
+ @java.lang.SuppressWarnings("all")
+ public BuilderOnNestedClass.Nested.NestedBuilder a(final String a) {
+ this.a = a;
+ return this;
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public BuilderOnNestedClass.Nested build() {
+ return new BuilderOnNestedClass.Nested(this.a);
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "BuilderOnNestedClass.Nested.NestedBuilder(a=" + this.a + ")";
+ }
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public static BuilderOnNestedClass.Nested.NestedBuilder builder() {
+ return new BuilderOnNestedClass.Nested.NestedBuilder();
+ }
+ }
+}
diff --git a/test/transform/resource/after-delombok/BuilderOnNestedRecord.java b/test/transform/resource/after-delombok/BuilderOnNestedRecord.java
new file mode 100644
index 00000000..83de7e06
--- /dev/null
+++ b/test/transform/resource/after-delombok/BuilderOnNestedRecord.java
@@ -0,0 +1,41 @@
+// version 14:
+public record BuilderOnNestedRecord(T t) {
+
+ public record Nested(String a) {
+
+ @java.lang.SuppressWarnings("all")
+ public static class NestedBuilder {
+ @java.lang.SuppressWarnings("all")
+ private String a;
+
+ @java.lang.SuppressWarnings("all")
+ NestedBuilder() {
+ }
+
+ /**
+ * @return {@code this}.
+ */
+ @java.lang.SuppressWarnings("all")
+ public BuilderOnNestedRecord.Nested.NestedBuilder a(final String a) {
+ this.a = a;
+ return this;
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public BuilderOnNestedRecord.Nested build() {
+ return new BuilderOnNestedRecord.Nested(this.a);
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "BuilderOnNestedRecord.Nested.NestedBuilder(a=" + this.a + ")";
+ }
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public static BuilderOnNestedRecord.Nested.NestedBuilder builder() {
+ return new BuilderOnNestedRecord.Nested.NestedBuilder();
+ }
+ }
+}
diff --git a/test/transform/resource/after-delombok/DelegateOnGetter.java b/test/transform/resource/after-delombok/DelegateOnGetter.java
index edf1641b..76794085 100644
--- a/test/transform/resource/after-delombok/DelegateOnGetter.java
+++ b/test/transform/resource/after-delombok/DelegateOnGetter.java
@@ -6,11 +6,11 @@ class DelegateOnGetter {
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public Bar getBar() {
- java.lang.Object value = this.bar.get();
- if (value == null) {
+ java.lang.Object $value = this.bar.get();
+ if ($value == null) {
synchronized (this.bar) {
- value = this.bar.get();
- if (value == null) {
+ $value = this.bar.get();
+ if ($value == null) {
final Bar actualValue = new Bar() {
public void setList(java.util.ArrayList list) {
}
@@ -18,12 +18,12 @@ class DelegateOnGetter {
return 42;
}
};
- value = actualValue == null ? this.bar : actualValue;
- this.bar.set(value);
+ $value = actualValue == null ? this.bar : actualValue;
+ this.bar.set($value);
}
}
}
- return (Bar) (value == this.bar ? null : value);
+ return (Bar) ($value == this.bar ? null : $value);
}
@java.lang.SuppressWarnings("all")
public void setList(final java.util.ArrayList list) {
diff --git a/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java
new file mode 100644
index 00000000..8c93c03d
--- /dev/null
+++ b/test/transform/resource/after-delombok/ExtensionMethodAmbiguousFunctional.java
@@ -0,0 +1,17 @@
+//skip-idempotent
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+class ExtensionMethodAmbiguousFunctional {
+ public void test() {
+ ExtensionMethodAmbiguousFunctional.Extensions.ambiguous("", System.out::println);
+ }
+
+ static class Extensions {
+ public static void ambiguous(T t, Function function) {
+ }
+
+ public static void ambiguous(T t, Consumer function) {
+ }
+ }
+}
diff --git a/test/transform/resource/after-delombok/GetterLazy.java b/test/transform/resource/after-delombok/GetterLazy.java
index 1e30f94b..8e1300be 100644
--- a/test/transform/resource/after-delombok/GetterLazy.java
+++ b/test/transform/resource/after-delombok/GetterLazy.java
@@ -4,17 +4,17 @@ class GetterLazy {
private final java.util.concurrent.atomic.AtomicReference fieldName = new java.util.concurrent.atomic.AtomicReference();
@java.lang.SuppressWarnings({"all", "unchecked"})
public ValueType getFieldName() {
- java.lang.Object value = this.fieldName.get();
- if (value == null) {
+ java.lang.Object $value = this.fieldName.get();
+ if ($value == null) {
synchronized (this.fieldName) {
- value = this.fieldName.get();
- if (value == null) {
+ $value = this.fieldName.get();
+ if ($value == null) {
final ValueType actualValue = new ValueType();
- value = actualValue == null ? this.fieldName : actualValue;
- this.fieldName.set(value);
+ $value = actualValue == null ? this.fieldName : actualValue;
+ this.fieldName.set($value);
}
}
}
- return (ValueType) (value == this.fieldName ? null : value);
+ return (ValueType) ($value == this.fieldName ? null : $value);
}
}
diff --git a/test/transform/resource/after-delombok/GetterLazyArguments.java b/test/transform/resource/after-delombok/GetterLazyArguments.java
index ef3f341c..00b17f5c 100644
--- a/test/transform/resource/after-delombok/GetterLazyArguments.java
+++ b/test/transform/resource/after-delombok/GetterLazyArguments.java
@@ -21,99 +21,99 @@ class GetterLazyArguments {
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField1() {
- java.lang.Object value = this.field1.get();
- if (value == null) {
+ java.lang.Object $value = this.field1.get();
+ if ($value == null) {
synchronized (this.field1) {
- value = this.field1.get();
- if (value == null) {
+ $value = this.field1.get();
+ if ($value == null) {
final String actualValue = stringInt(("a"), (1));
- value = actualValue == null ? this.field1 : actualValue;
- this.field1.set(value);
+ $value = actualValue == null ? this.field1 : actualValue;
+ this.field1.set($value);
}
}
}
- return (String) (value == this.field1 ? null : value);
+ return (String) ($value == this.field1 ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField2() {
- java.lang.Object value = this.field2.get();
- if (value == null) {
+ java.lang.Object $value = this.field2.get();
+ if ($value == null) {
synchronized (this.field2) {
- value = this.field2.get();
- if (value == null) {
+ $value = this.field2.get();
+ if ($value == null) {
final String actualValue = stringInt(true ? "a" : "b", true ? 1 : 0);
- value = actualValue == null ? this.field2 : actualValue;
- this.field2.set(value);
+ $value = actualValue == null ? this.field2 : actualValue;
+ this.field2.set($value);
}
}
}
- return (String) (value == this.field2 ? null : value);
+ return (String) ($value == this.field2 ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField3() {
- java.lang.Object value = this.field3.get();
- if (value == null) {
+ java.lang.Object $value = this.field3.get();
+ if ($value == null) {
synchronized (this.field3) {
- value = this.field3.get();
- if (value == null) {
+ $value = this.field3.get();
+ if ($value == null) {
final String actualValue = stringInt(("a"), true ? 1 : 0);
- value = actualValue == null ? this.field3 : actualValue;
- this.field3.set(value);
+ $value = actualValue == null ? this.field3 : actualValue;
+ this.field3.set($value);
}
}
}
- return (String) (value == this.field3 ? null : value);
+ return (String) ($value == this.field3 ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField4() {
- java.lang.Object value = this.field4.get();
- if (value == null) {
+ java.lang.Object $value = this.field4.get();
+ if ($value == null) {
synchronized (this.field4) {
- value = this.field4.get();
- if (value == null) {
+ $value = this.field4.get();
+ if ($value == null) {
final String actualValue = stringRunnable(fun(), () -> {
});
- value = actualValue == null ? this.field4 : actualValue;
- this.field4.set(value);
+ $value = actualValue == null ? this.field4 : actualValue;
+ this.field4.set($value);
}
}
}
- return (String) (value == this.field4 ? null : value);
+ return (String) ($value == this.field4 ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField5() {
- java.lang.Object value = this.field5.get();
- if (value == null) {
+ java.lang.Object $value = this.field5.get();
+ if ($value == null) {
synchronized (this.field5) {
- value = this.field5.get();
- if (value == null) {
+ $value = this.field5.get();
+ if ($value == null) {
final String actualValue = stringRunnable(("a"), () -> {
});
- value = actualValue == null ? this.field5 : actualValue;
- this.field5.set(value);
+ $value = actualValue == null ? this.field5 : actualValue;
+ this.field5.set($value);
}
}
}
- return (String) (value == this.field5 ? null : value);
+ return (String) ($value == this.field5 ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField6() {
- java.lang.Object value = this.field6.get();
- if (value == null) {
+ java.lang.Object $value = this.field6.get();
+ if ($value == null) {
synchronized (this.field6) {
- value = this.field6.get();
- if (value == null) {
+ $value = this.field6.get();
+ if ($value == null) {
final String actualValue = true ? stringInt(true ? "a" : "b", true ? 1 : 0) : "";
- value = actualValue == null ? this.field6 : actualValue;
- this.field6.set(value);
+ $value = actualValue == null ? this.field6 : actualValue;
+ this.field6.set($value);
}
}
}
- return (String) (value == this.field6 ? null : value);
+ return (String) ($value == this.field6 ? null : $value);
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-delombok/GetterLazyBoolean.java b/test/transform/resource/after-delombok/GetterLazyBoolean.java
index 5b1f19dc..495e6b92 100644
--- a/test/transform/resource/after-delombok/GetterLazyBoolean.java
+++ b/test/transform/resource/after-delombok/GetterLazyBoolean.java
@@ -33,32 +33,32 @@ class GetterLazyBoolean {
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public boolean isBooleanValue() {
- java.lang.Object value = this.booleanValue.get();
- if (value == null) {
+ java.lang.Object $value = this.booleanValue.get();
+ if ($value == null) {
synchronized (this.booleanValue) {
- value = this.booleanValue.get();
- if (value == null) {
+ $value = this.booleanValue.get();
+ if ($value == null) {
final boolean actualValue = calculateBoolean();
- value = actualValue;
- this.booleanValue.set(value);
+ $value = actualValue;
+ this.booleanValue.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public boolean isOtherBooleanValue() {
- java.lang.Object value = this.otherBooleanValue.get();
- if (value == null) {
+ java.lang.Object $value = this.otherBooleanValue.get();
+ if ($value == null) {
synchronized (this.otherBooleanValue) {
- value = this.otherBooleanValue.get();
- if (value == null) {
+ $value = this.otherBooleanValue.get();
+ if ($value == null) {
final boolean actualValue = !calculateBoolean();
- value = actualValue;
- this.otherBooleanValue.set(value);
+ $value = actualValue;
+ this.otherBooleanValue.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
}
diff --git a/test/transform/resource/after-delombok/GetterLazyEahcToString.java b/test/transform/resource/after-delombok/GetterLazyEahcToString.java
index bec89818..3742093b 100644
--- a/test/transform/resource/after-delombok/GetterLazyEahcToString.java
+++ b/test/transform/resource/after-delombok/GetterLazyEahcToString.java
@@ -46,18 +46,18 @@ class GetterLazyEahcToString {
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getValue() {
- java.lang.Object value = this.value.get();
- if (value == null) {
+ java.lang.Object $value = this.value.get();
+ if ($value == null) {
synchronized (this.value) {
- value = this.value.get();
- if (value == null) {
+ $value = this.value.get();
+ if ($value == null) {
final String actualValue = "";
- value = actualValue == null ? this.value : actualValue;
- this.value.set(value);
+ $value = actualValue == null ? this.value : actualValue;
+ this.value.set($value);
}
}
}
- return (String) (value == this.value ? null : value);
+ return (String) ($value == this.value ? null : $value);
}
@java.lang.SuppressWarnings("all")
diff --git a/test/transform/resource/after-delombok/GetterLazyErrorPosition.java b/test/transform/resource/after-delombok/GetterLazyErrorPosition.java
index 76797d44..c9013876 100644
--- a/test/transform/resource/after-delombok/GetterLazyErrorPosition.java
+++ b/test/transform/resource/after-delombok/GetterLazyErrorPosition.java
@@ -3,17 +3,17 @@ class GetterLazyErrorPosition {
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getField() {
- java.lang.Object value = this.field.get();
- if (value == null) {
+ java.lang.Object $value = this.field.get();
+ if ($value == null) {
synchronized (this.field) {
- value = this.field.get();
- if (value == null) {
+ $value = this.field.get();
+ if ($value == null) {
final String actualValue = true ? "" : new ErrorPosition();
- value = actualValue == null ? this.field : actualValue;
- this.field.set(value);
+ $value = actualValue == null ? this.field : actualValue;
+ this.field.set($value);
}
}
}
- return (String) (value == this.field ? null : value);
+ return (String) ($value == this.field ? null : $value);
}
}
diff --git a/test/transform/resource/after-delombok/GetterLazyGenerics.java b/test/transform/resource/after-delombok/GetterLazyGenerics.java
index 5e92cda7..a8b8ff6c 100644
--- a/test/transform/resource/after-delombok/GetterLazyGenerics.java
+++ b/test/transform/resource/after-delombok/GetterLazyGenerics.java
@@ -6,32 +6,32 @@ class GetterLazyGenerics {
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public E getField() {
- java.lang.Object value = this.field.get();
- if (value == null) {
+ java.lang.Object $value = this.field.get();
+ if ($value == null) {
synchronized (this.field) {
- value = this.field.get();
- if (value == null) {
+ $value = this.field.get();
+ if ($value == null) {
final E actualValue = getAny();
- value = actualValue == null ? this.field : actualValue;
- this.field.set(value);
+ $value = actualValue == null ? this.field : actualValue;
+ this.field.set($value);
}
}
}
- return (E) (value == this.field ? null : value);
+ return (E) ($value == this.field ? null : $value);
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public long getField2() {
- java.lang.Object value = this.field2.get();
- if (value == null) {
+ java.lang.Object $value = this.field2.get();
+ if ($value == null) {
synchronized (this.field2) {
- value = this.field2.get();
- if (value == null) {
+ $value = this.field2.get();
+ if ($value == null) {
final long actualValue = System.currentTimeMillis();
- value = actualValue;
- this.field2.set(value);
+ $value = actualValue;
+ this.field2.set($value);
}
}
}
- return (java.lang.Long) value;
+ return (java.lang.Long) $value;
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java b/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java
index 4476e463..199437a1 100644
--- a/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java
+++ b/test/transform/resource/after-delombok/GetterLazyInAnonymousClass.java
@@ -6,18 +6,18 @@ public class GetterLazyInAnonymousClass {
@java.lang.SuppressWarnings({"all", "unchecked"})
public String getString() {
- java.lang.Object value = this.string.get();
- if (value == null) {
+ java.lang.Object $value = this.string.get();
+ if ($value == null) {
synchronized (this.string) {
- value = this.string.get();
- if (value == null) {
+ $value = this.string.get();
+ if ($value == null) {
final String actualValue = "test";
- value = actualValue == null ? this.string : actualValue;
- this.string.set(value);
+ $value = actualValue == null ? this.string : actualValue;
+ this.string.set($value);
}
}
}
- return (String) (value == this.string ? null : value);
+ return (String) ($value == this.string ? null : $value);
}
}
};
diff --git a/test/transform/resource/after-delombok/GetterLazyNative.java b/test/transform/resource/after-delombok/GetterLazyNative.java
index f43d5490..a71a0354 100644
--- a/test/transform/resource/after-delombok/GetterLazyNative.java
+++ b/test/transform/resource/after-delombok/GetterLazyNative.java
@@ -10,137 +10,137 @@ class GetterLazyNative {
private final java.util.concurrent.atomic.AtomicReference intArrayField = new java.util.concurrent.atomic.AtomicReference();
@java.lang.SuppressWarnings({"all", "unchecked"})
public boolean isBooleanField() {
- java.lang.Object value = this.booleanField.get();
- if (value == null) {
+ java.lang.Object $value = this.booleanField.get();
+ if ($value == null) {
synchronized (this.booleanField) {
- value = this.booleanField.get();
- if (value == null) {
+ $value = this.booleanField.get();
+ if ($value == null) {
final boolean actualValue = true;
- value = actualValue;
- this.booleanField.set(value);
+ $value = actualValue;
+ this.booleanField.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public byte getByteField() {
- java.lang.Object value = this.byteField.get();
- if (value == null) {
+ java.lang.Object $value = this.byteField.get();
+ if ($value == null) {
synchronized (this.byteField) {
- value = this.byteField.get();
- if (value == null) {
+ $value = this.byteField.get();
+ if ($value == null) {
final byte actualValue = 1;
- value = actualValue;
- this.byteField.set(value);
+ $value = actualValue;
+ this.byteField.set($value);
}
}
}
- return (java.lang.Byte) value;
+ return (java.lang.Byte) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public short getShortField() {
- java.lang.Object value = this.shortField.get();
- if (value == null) {
+ java.lang.Object $value = this.shortField.get();
+ if ($value == null) {
synchronized (this.shortField) {
- value = this.shortField.get();
- if (value == null) {
+ $value = this.shortField.get();
+ if ($value == null) {
final short actualValue = 1;
- value = actualValue;
- this.shortField.set(value);
+ $value = actualValue;
+ this.shortField.set($value);
}
}
}
- return (java.lang.Short) value;
+ return (java.lang.Short) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public int getIntField() {
- java.lang.Object value = this.intField.get();
- if (value == null) {
+ java.lang.Object $value = this.intField.get();
+ if ($value == null) {
synchronized (this.intField) {
- value = this.intField.get();
- if (value == null) {
+ $value = this.intField.get();
+ if ($value == null) {
final int actualValue = 1;
- value = actualValue;
- this.intField.set(value);
+ $value = actualValue;
+ this.intField.set($value);
}
}
}
- return (java.lang.Integer) value;
+ return (java.lang.Integer) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public long getLongField() {
- java.lang.Object value = this.longField.get();
- if (value == null) {
+ java.lang.Object $value = this.longField.get();
+ if ($value == null) {
synchronized (this.longField) {
- value = this.longField.get();
- if (value == null) {
+ $value = this.longField.get();
+ if ($value == null) {
final long actualValue = 1;
- value = actualValue;
- this.longField.set(value);
+ $value = actualValue;
+ this.longField.set($value);
}
}
}
- return (java.lang.Long) value;
+ return (java.lang.Long) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public float getFloatField() {
- java.lang.Object value = this.floatField.get();
- if (value == null) {
+ java.lang.Object $value = this.floatField.get();
+ if ($value == null) {
synchronized (this.floatField) {
- value = this.floatField.get();
- if (value == null) {
+ $value = this.floatField.get();
+ if ($value == null) {
final float actualValue = 1.0F;
- value = actualValue;
- this.floatField.set(value);
+ $value = actualValue;
+ this.floatField.set($value);
}
}
}
- return (java.lang.Float) value;
+ return (java.lang.Float) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public double getDoubleField() {
- java.lang.Object value = this.doubleField.get();
- if (value == null) {
+ java.lang.Object $value = this.doubleField.get();
+ if ($value == null) {
synchronized (this.doubleField) {
- value = this.doubleField.get();
- if (value == null) {
+ $value = this.doubleField.get();
+ if ($value == null) {
final double actualValue = 1.0;
- value = actualValue;
- this.doubleField.set(value);
+ $value = actualValue;
+ this.doubleField.set($value);
}
}
}
- return (java.lang.Double) value;
+ return (java.lang.Double) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public char getCharField() {
- java.lang.Object value = this.charField.get();
- if (value == null) {
+ java.lang.Object $value = this.charField.get();
+ if ($value == null) {
synchronized (this.charField) {
- value = this.charField.get();
- if (value == null) {
+ $value = this.charField.get();
+ if ($value == null) {
final char actualValue = '1';
- value = actualValue;
- this.charField.set(value);
+ $value = actualValue;
+ this.charField.set($value);
}
}
}
- return (java.lang.Character) value;
+ return (java.lang.Character) $value;
}
@java.lang.SuppressWarnings({"all", "unchecked"})
public int[] getIntArrayField() {
- java.lang.Object value = this.intArrayField.get();
- if (value == null) {
+ java.lang.Object $value = this.intArrayField.get();
+ if ($value == null) {
synchronized (this.intArrayField) {
- value = this.intArrayField.get();
- if (value == null) {
+ $value = this.intArrayField.get();
+ if ($value == null) {
final int[] actualValue = new int[] {1};
- value = actualValue == null ? this.intArrayField : actualValue;
- this.intArrayField.set(value);
+ $value = actualValue == null ? this.intArrayField : actualValue;
+ this.intArrayField.set($value);
}
}
}
- return (int[]) (value == this.intArrayField ? null : value);
+ return (int[]) ($value == this.intArrayField ? null : $value);
}
}
diff --git a/test/transform/resource/after-delombok/GetterLazyTransient.java b/test/transform/resource/after-delombok/GetterLazyTransient.java
index 0fd85621..3d1a2be3 100644
--- a/test/transform/resource/after-delombok/GetterLazyTransient.java
+++ b/test/transform/resource/after-delombok/GetterLazyTransient.java
@@ -4,18 +4,18 @@ class GetterLazyTransient {
private final transient int nonLazyTransientField = 3;
@java.lang.SuppressWarnings({"all", "unchecked"})
public int getNonTransientField() {
- java.lang.Object value = this.nonTransientField.get();
- if (value == null) {
+ java.lang.Object $value = this.nonTransientField.get();
+ if ($value == null) {
synchronized (this.nonTransientField) {
- value = this.nonTransientField.get();
- if (value == null) {
+ $value = this.nonTransientField.get();
+ if ($value == null) {
final int actualValue = 1;
- value = actualValue;
- this.nonTransientField.set(value);
+ $value = actualValue;
+ this.nonTransientField.set($value);
}
}
}
- return (java.lang.Integer) value;
+ return (java.lang.Integer) $value;
}
@java.lang.SuppressWarnings("all")
public int getNonLazyTransientField() {
diff --git a/test/transform/resource/after-delombok/LockedInInitializer.java b/test/transform/resource/after-delombok/LockedInInitializer.java
new file mode 100644
index 00000000..a4b687fc
--- /dev/null
+++ b/test/transform/resource/after-delombok/LockedInInitializer.java
@@ -0,0 +1,41 @@
+public class LockedInInitializer {
+ public static final Runnable LOCKED = new Runnable() {
+ @java.lang.SuppressWarnings("all")
+ private final java.util.concurrent.locks.Lock $lock = new java.util.concurrent.locks.ReentrantLock();
+ @Override
+ public void run() {
+ this.$lock.lock();
+ try {
+ System.out.println("test");
+ } finally {
+ this.$lock.unlock();
+ }
+ }
+ };
+ public static final Runnable LOCKED_READ = new Runnable() {
+ @java.lang.SuppressWarnings("all")
+ private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
+ @Override
+ public void run() {
+ this.$lock.readLock().lock();
+ try {
+ System.out.println("test");
+ } finally {
+ this.$lock.readLock().unlock();
+ }
+ }
+ };
+ public static final Runnable LOCKED_WRITE = new Runnable() {
+ @java.lang.SuppressWarnings("all")
+ private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
+ @Override
+ public void run() {
+ this.$lock.writeLock().lock();
+ try {
+ System.out.println("test");
+ } finally {
+ this.$lock.writeLock().unlock();
+ }
+ }
+ };
+}
diff --git a/test/transform/resource/after-delombok/SkipSuppressWarnings.java b/test/transform/resource/after-delombok/SkipSuppressWarnings.java
index 151d4e17..77bfdcc4 100644
--- a/test/transform/resource/after-delombok/SkipSuppressWarnings.java
+++ b/test/transform/resource/after-delombok/SkipSuppressWarnings.java
@@ -8,17 +8,17 @@ class SkipSuppressWarnings {
@java.lang.SuppressWarnings({"unchecked"})
public String getField2() {
- java.lang.Object value = this.field2.get();
- if (value == null) {
+ java.lang.Object $value = this.field2.get();
+ if ($value == null) {
synchronized (this.field2) {
- value = this.field2.get();
- if (value == null) {
+ $value = this.field2.get();
+ if ($value == null) {
final String actualValue = "";
- value = actualValue == null ? this.field2 : actualValue;
- this.field2.set(value);
+ $value = actualValue == null ? this.field2 : actualValue;
+ this.field2.set($value);
}
}
}
- return (String) (value == this.field2 ? null : value);
+ return (String) ($value == this.field2 ? null : $value);
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java b/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java
new file mode 100644
index 00000000..b47dadc4
--- /dev/null
+++ b/test/transform/resource/after-delombok/SneakyThrowsInInitializer.java
@@ -0,0 +1,12 @@
+public class SneakyThrowsInInitializer {
+ public static final Runnable R = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ System.out.println("test");
+ } catch (final java.lang.Throwable $ex) {
+ throw lombok.Lombok.sneakyThrow($ex);
+ }
+ }
+ };
+}
diff --git a/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java
new file mode 100644
index 00000000..f7ffe2fd
--- /dev/null
+++ b/test/transform/resource/after-delombok/SuperBuilderWithAnnotatedTypeParam.java
@@ -0,0 +1,118 @@
+//version 8:
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+public class SuperBuilderWithAnnotatedTypeParam {
+ @Documented
+ @Target({ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE})
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MyAnnotation {
+ }
+ public static class Parent {
+ A field1;
+ @java.lang.SuppressWarnings("all")
+ public static abstract class ParentBuilder, B extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder> {
+ @java.lang.SuppressWarnings("all")
+ private A field1;
+ /**
+ * @return {@code this}.
+ */
+ @java.lang.SuppressWarnings("all")
+ public B field1(final A field1) {
+ this.field1 = field1;
+ return self();
+ }
+ @java.lang.SuppressWarnings("all")
+ protected abstract B self();
+ @java.lang.SuppressWarnings("all")
+ public abstract C build();
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder(field1=" + this.field1 + ")";
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ private static final class ParentBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder, SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl> {
+ @java.lang.SuppressWarnings("all")
+ private ParentBuilderImpl() {
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ protected SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl self() {
+ return this;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public SuperBuilderWithAnnotatedTypeParam.Parent build() {
+ return new SuperBuilderWithAnnotatedTypeParam.Parent(this);
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ protected Parent(final SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder b) {
+ this.field1 = b.field1;
+ }
+ @java.lang.SuppressWarnings("all")
+ public static SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder builder() {
+ return new SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl();
+ }
+ }
+ public static class Child extends Parent<@MyAnnotation String> {
+ double field3;
+ @java.lang.SuppressWarnings("all")
+ public static abstract class ChildBuilder> extends Parent.ParentBuilder<@MyAnnotation String, C, B> {
+ @java.lang.SuppressWarnings("all")
+ private double field3;
+ /**
+ * @return {@code this}.
+ */
+ @java.lang.SuppressWarnings("all")
+ public B field3(final double field3) {
+ this.field3 = field3;
+ return self();
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ protected abstract B self();
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public abstract C build();
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String toString() {
+ return "SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder(super=" + super.toString() + ", field3=" + this.field3 + ")";
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ private static final class ChildBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder {
+ @java.lang.SuppressWarnings("all")
+ private ChildBuilderImpl() {
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ protected SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl self() {
+ return this;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public SuperBuilderWithAnnotatedTypeParam.Child build() {
+ return new SuperBuilderWithAnnotatedTypeParam.Child(this);
+ }
+ }
+ @java.lang.SuppressWarnings("all")
+ protected Child(final SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder, ?> b) {
+ super(b);
+ this.field3 = b.field3;
+ }
+ @java.lang.SuppressWarnings("all")
+ public static SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder, ?> builder() {
+ return new SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl();
+ }
+ }
+ public static void test() {
+ Child x = Child.builder().field3(0.0).field1("string").build();
+ }
+}
diff --git a/test/transform/resource/after-delombok/SynchronizedInInitializer.java b/test/transform/resource/after-delombok/SynchronizedInInitializer.java
new file mode 100644
index 00000000..c63f4e74
--- /dev/null
+++ b/test/transform/resource/after-delombok/SynchronizedInInitializer.java
@@ -0,0 +1,12 @@
+public class SynchronizedInInitializer {
+ public static final Runnable SYNCHRONIZED = new Runnable() {
+ @java.lang.SuppressWarnings("all")
+ private final java.lang.Object $lock = new java.lang.Object[0];
+ @Override
+ public void run() {
+ synchronized (this.$lock) {
+ System.out.println("test");
+ }
+ }
+ };
+}
diff --git a/test/transform/resource/after-delombok/WithOnNestedRecord.java b/test/transform/resource/after-delombok/WithOnNestedRecord.java
new file mode 100644
index 00000000..89a75478
--- /dev/null
+++ b/test/transform/resource/after-delombok/WithOnNestedRecord.java
@@ -0,0 +1,21 @@
+// version 14:
+public record WithOnNestedRecord() {
+
+ public record Nested(String a, String b) {
+ /**
+ * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
+ */
+ @java.lang.SuppressWarnings("all")
+ public WithOnNestedRecord.Nested withA(final String a) {
+ return this.a == a ? this : new WithOnNestedRecord.Nested(a, this.b);
+ }
+
+ /**
+ * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
+ */
+ @java.lang.SuppressWarnings("all")
+ public WithOnNestedRecord.Nested withB(final String b) {
+ return this.b == b ? this : new WithOnNestedRecord.Nested(this.a, b);
+ }
+ }
+}
diff --git a/test/transform/resource/after-ecj/BuilderOnNestedClass.java b/test/transform/resource/after-ecj/BuilderOnNestedClass.java
new file mode 100644
index 00000000..b100223b
--- /dev/null
+++ b/test/transform/resource/after-ecj/BuilderOnNestedClass.java
@@ -0,0 +1,35 @@
+public class BuilderOnNestedClass {
+ public static @lombok.Builder class Nested {
+ public static @java.lang.SuppressWarnings("all") class NestedBuilder {
+ private @java.lang.SuppressWarnings("all") String a;
+ @java.lang.SuppressWarnings("all") NestedBuilder() {
+ super();
+ }
+ /**
+ * @return {@code this}.
+ */
+ public @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested.NestedBuilder a(final String a) {
+ this.a = a;
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested build() {
+ return new BuilderOnNestedClass.Nested(this.a);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (("BuilderOnNestedClass.Nested.NestedBuilder(a=" + this.a) + ")");
+ }
+ }
+ private String a;
+ @java.lang.SuppressWarnings("all") Nested(final String a) {
+ super();
+ this.a = a;
+ }
+ public static @java.lang.SuppressWarnings("all") BuilderOnNestedClass.Nested.NestedBuilder builder() {
+ return new BuilderOnNestedClass.Nested.NestedBuilder();
+ }
+ }
+ private T t;
+ public BuilderOnNestedClass() {
+ super();
+ }
+}
diff --git a/test/transform/resource/after-ecj/BuilderOnNestedRecord.java b/test/transform/resource/after-ecj/BuilderOnNestedRecord.java
new file mode 100644
index 00000000..4e025485
--- /dev/null
+++ b/test/transform/resource/after-ecj/BuilderOnNestedRecord.java
@@ -0,0 +1,30 @@
+public record BuilderOnNestedRecord(T t) {
+ public @lombok.Builder record Nested(String a) {
+ public static @java.lang.SuppressWarnings("all") class NestedBuilder {
+ private @java.lang.SuppressWarnings("all") String a;
+ @java.lang.SuppressWarnings("all") NestedBuilder() {
+ super();
+ }
+ /**
+ * @return {@code this}.
+ */
+ public @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested.NestedBuilder a(final String a) {
+ this.a = a;
+ return this;
+ }
+ public @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested build() {
+ return new BuilderOnNestedRecord.Nested(this.a);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (("BuilderOnNestedRecord.Nested.NestedBuilder(a=" + this.a) + ")");
+ }
+ }
+/* Implicit */ private final String a;
+
+ public static @java.lang.SuppressWarnings("all") BuilderOnNestedRecord.Nested.NestedBuilder builder() {
+ return new BuilderOnNestedRecord.Nested.NestedBuilder();
+ }
+ }
+/* Implicit */ private final T t;
+
+}
diff --git a/test/transform/resource/after-ecj/DelegateOnGetter.java b/test/transform/resource/after-ecj/DelegateOnGetter.java
index f2b9a6cd..c23ea917 100644
--- a/test/transform/resource/after-ecj/DelegateOnGetter.java
+++ b/test/transform/resource/after-ecj/DelegateOnGetter.java
@@ -10,13 +10,13 @@ class DelegateOnGetter {
super();
}
public @Delegate @java.lang.SuppressWarnings({"all", "unchecked"}) Bar getBar() {
- java.lang.Object value = this.bar.get();
- if ((value == null))
+ java.lang.Object $value = this.bar.get();
+ if (($value == null))
{
synchronized (this.bar)
{
- value = this.bar.get();
- if ((value == null))
+ $value = this.bar.get();
+ if (($value == null))
{
final Bar actualValue = new Bar() {
x() {
@@ -28,12 +28,12 @@ class DelegateOnGetter {
return 42;
}
};
- value = ((actualValue == null) ? this.bar : actualValue);
- this.bar.set(value);
+ $value = ((actualValue == null) ? this.bar : actualValue);
+ this.bar.set($value);
}
}
}
- return (Bar) ((value == this.bar) ? null : value);
+ return (Bar) (($value == this.bar) ? null : $value);
}
public @java.lang.SuppressWarnings("all") int getInt() {
return this.getBar().getInt();
diff --git a/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java
new file mode 100644
index 00000000..80d216b2
--- /dev/null
+++ b/test/transform/resource/after-ecj/ExtensionMethodAmbiguousFunctional.java
@@ -0,0 +1,20 @@
+import java.util.function.Consumer;
+import java.util.function.Function;
+import lombok.experimental.ExtensionMethod;
+@ExtensionMethod({ExtensionMethodAmbiguousFunctional.Extensions.class}) class ExtensionMethodAmbiguousFunctional {
+ static class Extensions {
+ Extensions() {
+ super();
+ }
+ public static void ambiguous(T t, Function function) {
+ }
+ public static void ambiguous(T t, Consumer function) {
+ }
+ }
+ ExtensionMethodAmbiguousFunctional() {
+ super();
+ }
+ public void test() {
+ "".ambiguous(System.out::println);
+ }
+}
diff --git a/test/transform/resource/after-ecj/GetterLazy.java b/test/transform/resource/after-ecj/GetterLazy.java
index b4567f04..7627ab16 100644
--- a/test/transform/resource/after-ecj/GetterLazy.java
+++ b/test/transform/resource/after-ecj/GetterLazy.java
@@ -9,20 +9,20 @@ class GetterLazy {
super();
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) ValueType getFieldName() {
- java.lang.Object value = this.fieldName.get();
- if ((value == null))
+ java.lang.Object $value = this.fieldName.get();
+ if (($value == null))
{
synchronized (this.fieldName)
{
- value = this.fieldName.get();
- if ((value == null))
+ $value = this.fieldName.get();
+ if (($value == null))
{
final ValueType actualValue = new ValueType();
- value = ((actualValue == null) ? this.fieldName : actualValue);
- this.fieldName.set(value);
+ $value = ((actualValue == null) ? this.fieldName : actualValue);
+ this.fieldName.set($value);
}
}
}
- return (ValueType) ((value == this.fieldName) ? null : value);
+ return (ValueType) (($value == this.fieldName) ? null : $value);
}
}
diff --git a/test/transform/resource/after-ecj/GetterLazyArguments.java b/test/transform/resource/after-ecj/GetterLazyArguments.java
index 14086d81..bb51c4fc 100644
--- a/test/transform/resource/after-ecj/GetterLazyArguments.java
+++ b/test/transform/resource/after-ecj/GetterLazyArguments.java
@@ -18,107 +18,107 @@ class GetterLazyArguments {
return null;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField1() {
- java.lang.Object value = this.field1.get();
- if ((value == null))
+ java.lang.Object $value = this.field1.get();
+ if (($value == null))
{
synchronized (this.field1)
{
- value = this.field1.get();
- if ((value == null))
+ $value = this.field1.get();
+ if (($value == null))
{
final String actualValue = stringInt("a", 1);
- value = ((actualValue == null) ? this.field1 : actualValue);
- this.field1.set(value);
+ $value = ((actualValue == null) ? this.field1 : actualValue);
+ this.field1.set($value);
}
}
}
- return (String) ((value == this.field1) ? null : value);
+ return (String) (($value == this.field1) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField2() {
- java.lang.Object value = this.field2.get();
- if ((value == null))
+ java.lang.Object $value = this.field2.get();
+ if (($value == null))
{
synchronized (this.field2)
{
- value = this.field2.get();
- if ((value == null))
+ $value = this.field2.get();
+ if (($value == null))
{
final String actualValue = stringInt((true ? "a" : "b"), (true ? 1 : 0));
- value = ((actualValue == null) ? this.field2 : actualValue);
- this.field2.set(value);
+ $value = ((actualValue == null) ? this.field2 : actualValue);
+ this.field2.set($value);
}
}
}
- return (String) ((value == this.field2) ? null : value);
+ return (String) (($value == this.field2) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField3() {
- java.lang.Object value = this.field3.get();
- if ((value == null))
+ java.lang.Object $value = this.field3.get();
+ if (($value == null))
{
synchronized (this.field3)
{
- value = this.field3.get();
- if ((value == null))
+ $value = this.field3.get();
+ if (($value == null))
{
final String actualValue = stringInt("a", (true ? 1 : 0));
- value = ((actualValue == null) ? this.field3 : actualValue);
- this.field3.set(value);
+ $value = ((actualValue == null) ? this.field3 : actualValue);
+ this.field3.set($value);
}
}
}
- return (String) ((value == this.field3) ? null : value);
+ return (String) (($value == this.field3) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField4() {
- java.lang.Object value = this.field4.get();
- if ((value == null))
+ java.lang.Object $value = this.field4.get();
+ if (($value == null))
{
synchronized (this.field4)
{
- value = this.field4.get();
- if ((value == null))
+ $value = this.field4.get();
+ if (($value == null))
{
final String actualValue = stringRunnable(fun(), () -> {
});
- value = ((actualValue == null) ? this.field4 : actualValue);
- this.field4.set(value);
+ $value = ((actualValue == null) ? this.field4 : actualValue);
+ this.field4.set($value);
}
}
}
- return (String) ((value == this.field4) ? null : value);
+ return (String) (($value == this.field4) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField5() {
- java.lang.Object value = this.field5.get();
- if ((value == null))
+ java.lang.Object $value = this.field5.get();
+ if (($value == null))
{
synchronized (this.field5)
{
- value = this.field5.get();
- if ((value == null))
+ $value = this.field5.get();
+ if (($value == null))
{
final String actualValue = stringRunnable("a", () -> {
});
- value = ((actualValue == null) ? this.field5 : actualValue);
- this.field5.set(value);
+ $value = ((actualValue == null) ? this.field5 : actualValue);
+ this.field5.set($value);
}
}
}
- return (String) ((value == this.field5) ? null : value);
+ return (String) (($value == this.field5) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getField6() {
- java.lang.Object value = this.field6.get();
- if ((value == null))
+ java.lang.Object $value = this.field6.get();
+ if (($value == null))
{
synchronized (this.field6)
{
- value = this.field6.get();
- if ((value == null))
+ $value = this.field6.get();
+ if (($value == null))
{
final String actualValue = (true ? stringInt((true ? "a" : "b"), (true ? 1 : 0)) : "");
- value = ((actualValue == null) ? this.field6 : actualValue);
- this.field6.set(value);
+ $value = ((actualValue == null) ? this.field6 : actualValue);
+ this.field6.set($value);
}
}
}
- return (String) ((value == this.field6) ? null : value);
+ return (String) (($value == this.field6) ? null : $value);
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-ecj/GetterLazyBoolean.java b/test/transform/resource/after-ecj/GetterLazyBoolean.java
index ad319755..40ecb856 100644
--- a/test/transform/resource/after-ecj/GetterLazyBoolean.java
+++ b/test/transform/resource/after-ecj/GetterLazyBoolean.java
@@ -8,38 +8,38 @@
return true;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isBooleanValue() {
- java.lang.Object value = this.booleanValue.get();
- if ((value == null))
+ java.lang.Object $value = this.booleanValue.get();
+ if (($value == null))
{
synchronized (this.booleanValue)
{
- value = this.booleanValue.get();
- if ((value == null))
+ $value = this.booleanValue.get();
+ if (($value == null))
{
final boolean actualValue = calculateBoolean();
- value = actualValue;
- this.booleanValue.set(value);
+ $value = actualValue;
+ this.booleanValue.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isOtherBooleanValue() {
- java.lang.Object value = this.otherBooleanValue.get();
- if ((value == null))
+ java.lang.Object $value = this.otherBooleanValue.get();
+ if (($value == null))
{
synchronized (this.otherBooleanValue)
{
- value = this.otherBooleanValue.get();
- if ((value == null))
+ $value = this.otherBooleanValue.get();
+ if (($value == null))
{
final boolean actualValue = (! calculateBoolean());
- value = actualValue;
- this.otherBooleanValue.set(value);
+ $value = actualValue;
+ this.otherBooleanValue.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
if ((o == this))
diff --git a/test/transform/resource/after-ecj/GetterLazyEahcToString.java b/test/transform/resource/after-ecj/GetterLazyEahcToString.java
index 5197f4e1..f4f4ed37 100644
--- a/test/transform/resource/after-ecj/GetterLazyEahcToString.java
+++ b/test/transform/resource/after-ecj/GetterLazyEahcToString.java
@@ -5,21 +5,21 @@
super();
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getValue() {
- java.lang.Object value = this.value.get();
- if ((value == null))
+ java.lang.Object $value = this.value.get();
+ if (($value == null))
{
synchronized (this.value)
{
- value = this.value.get();
- if ((value == null))
+ $value = this.value.get();
+ if (($value == null))
{
final String actualValue = "";
- value = ((actualValue == null) ? this.value : actualValue);
- this.value.set(value);
+ $value = ((actualValue == null) ? this.value : actualValue);
+ this.value.set($value);
}
}
}
- return (String) ((value == this.value) ? null : value);
+ return (String) (($value == this.value) ? null : $value);
}
public @java.lang.SuppressWarnings("all") String getValue2() {
return this.value2;
diff --git a/test/transform/resource/after-ecj/GetterLazyGenerics.java b/test/transform/resource/after-ecj/GetterLazyGenerics.java
index 67ef5543..3a2a06c1 100644
--- a/test/transform/resource/after-ecj/GetterLazyGenerics.java
+++ b/test/transform/resource/after-ecj/GetterLazyGenerics.java
@@ -8,37 +8,37 @@ class GetterLazyGenerics {
return null;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) E getField() {
- java.lang.Object value = this.field.get();
- if ((value == null))
+ java.lang.Object $value = this.field.get();
+ if (($value == null))
{
synchronized (this.field)
{
- value = this.field.get();
- if ((value == null))
+ $value = this.field.get();
+ if (($value == null))
{
final E actualValue = getAny();
- value = ((actualValue == null) ? this.field : actualValue);
- this.field.set(value);
+ $value = ((actualValue == null) ? this.field : actualValue);
+ this.field.set($value);
}
}
}
- return (E) ((value == this.field) ? null : value);
+ return (E) (($value == this.field) ? null : $value);
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) long getField2() {
- java.lang.Object value = this.field2.get();
- if ((value == null))
+ java.lang.Object $value = this.field2.get();
+ if (($value == null))
{
synchronized (this.field2)
{
- value = this.field2.get();
- if ((value == null))
+ $value = this.field2.get();
+ if (($value == null))
{
final long actualValue = System.currentTimeMillis();
- value = actualValue;
- this.field2.set(value);
+ $value = actualValue;
+ this.field2.set($value);
}
}
}
- return (java.lang.Long) value;
+ return (java.lang.Long) $value;
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java b/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java
index ab8bc599..dadd8e71 100644
--- a/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java
+++ b/test/transform/resource/after-ecj/GetterLazyInAnonymousClass.java
@@ -7,21 +7,21 @@ public class GetterLazyInAnonymousClass {
super();
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) String getString() {
- java.lang.Object value = this.string.get();
- if ((value == null))
+ java.lang.Object $value = this.string.get();
+ if (($value == null))
{
synchronized (this.string)
{
- value = this.string.get();
- if ((value == null))
+ $value = this.string.get();
+ if (($value == null))
{
final String actualValue = "test";
- value = ((actualValue == null) ? this.string : actualValue);
- this.string.set(value);
+ $value = ((actualValue == null) ? this.string : actualValue);
+ this.string.set($value);
}
}
}
- return (String) ((value == this.string) ? null : value);
+ return (String) (($value == this.string) ? null : $value);
}
}
x() {
diff --git a/test/transform/resource/after-ecj/GetterLazyNative.java b/test/transform/resource/after-ecj/GetterLazyNative.java
index 7808068e..c2769c51 100644
--- a/test/transform/resource/after-ecj/GetterLazyNative.java
+++ b/test/transform/resource/after-ecj/GetterLazyNative.java
@@ -12,156 +12,156 @@ class GetterLazyNative {
super();
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) boolean isBooleanField() {
- java.lang.Object value = this.booleanField.get();
- if ((value == null))
+ java.lang.Object $value = this.booleanField.get();
+ if (($value == null))
{
synchronized (this.booleanField)
{
- value = this.booleanField.get();
- if ((value == null))
+ $value = this.booleanField.get();
+ if (($value == null))
{
final boolean actualValue = true;
- value = actualValue;
- this.booleanField.set(value);
+ $value = actualValue;
+ this.booleanField.set($value);
}
}
}
- return (java.lang.Boolean) value;
+ return (java.lang.Boolean) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) byte getByteField() {
- java.lang.Object value = this.byteField.get();
- if ((value == null))
+ java.lang.Object $value = this.byteField.get();
+ if (($value == null))
{
synchronized (this.byteField)
{
- value = this.byteField.get();
- if ((value == null))
+ $value = this.byteField.get();
+ if (($value == null))
{
final byte actualValue = 1;
- value = actualValue;
- this.byteField.set(value);
+ $value = actualValue;
+ this.byteField.set($value);
}
}
}
- return (java.lang.Byte) value;
+ return (java.lang.Byte) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) short getShortField() {
- java.lang.Object value = this.shortField.get();
- if ((value == null))
+ java.lang.Object $value = this.shortField.get();
+ if (($value == null))
{
synchronized (this.shortField)
{
- value = this.shortField.get();
- if ((value == null))
+ $value = this.shortField.get();
+ if (($value == null))
{
final short actualValue = 1;
- value = actualValue;
- this.shortField.set(value);
+ $value = actualValue;
+ this.shortField.set($value);
}
}
}
- return (java.lang.Short) value;
+ return (java.lang.Short) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) int getIntField() {
- java.lang.Object value = this.intField.get();
- if ((value == null))
+ java.lang.Object $value = this.intField.get();
+ if (($value == null))
{
synchronized (this.intField)
{
- value = this.intField.get();
- if ((value == null))
+ $value = this.intField.get();
+ if (($value == null))
{
final int actualValue = 1;
- value = actualValue;
- this.intField.set(value);
+ $value = actualValue;
+ this.intField.set($value);
}
}
}
- return (java.lang.Integer) value;
+ return (java.lang.Integer) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) long getLongField() {
- java.lang.Object value = this.longField.get();
- if ((value == null))
+ java.lang.Object $value = this.longField.get();
+ if (($value == null))
{
synchronized (this.longField)
{
- value = this.longField.get();
- if ((value == null))
+ $value = this.longField.get();
+ if (($value == null))
{
final long actualValue = 1;
- value = actualValue;
- this.longField.set(value);
+ $value = actualValue;
+ this.longField.set($value);
}
}
}
- return (java.lang.Long) value;
+ return (java.lang.Long) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) float getFloatField() {
- java.lang.Object value = this.floatField.get();
- if ((value == null))
+ java.lang.Object $value = this.floatField.get();
+ if (($value == null))
{
synchronized (this.floatField)
{
- value = this.floatField.get();
- if ((value == null))
+ $value = this.floatField.get();
+ if (($value == null))
{
final float actualValue = 1.0f;
- value = actualValue;
- this.floatField.set(value);
+ $value = actualValue;
+ this.floatField.set($value);
}
}
}
- return (java.lang.Float) value;
+ return (java.lang.Float) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) double getDoubleField() {
- java.lang.Object value = this.doubleField.get();
- if ((value == null))
+ java.lang.Object $value = this.doubleField.get();
+ if (($value == null))
{
synchronized (this.doubleField)
{
- value = this.doubleField.get();
- if ((value == null))
+ $value = this.doubleField.get();
+ if (($value == null))
{
final double actualValue = 1.0;
- value = actualValue;
- this.doubleField.set(value);
+ $value = actualValue;
+ this.doubleField.set($value);
}
}
}
- return (java.lang.Double) value;
+ return (java.lang.Double) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) char getCharField() {
- java.lang.Object value = this.charField.get();
- if ((value == null))
+ java.lang.Object $value = this.charField.get();
+ if (($value == null))
{
synchronized (this.charField)
{
- value = this.charField.get();
- if ((value == null))
+ $value = this.charField.get();
+ if (($value == null))
{
final char actualValue = '1';
- value = actualValue;
- this.charField.set(value);
+ $value = actualValue;
+ this.charField.set($value);
}
}
}
- return (java.lang.Character) value;
+ return (java.lang.Character) $value;
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) int[] getIntArrayField() {
- java.lang.Object value = this.intArrayField.get();
- if ((value == null))
+ java.lang.Object $value = this.intArrayField.get();
+ if (($value == null))
{
synchronized (this.intArrayField)
{
- value = this.intArrayField.get();
- if ((value == null))
+ $value = this.intArrayField.get();
+ if (($value == null))
{
final int[] actualValue = new int[]{1};
- value = ((actualValue == null) ? this.intArrayField : actualValue);
- this.intArrayField.set(value);
+ $value = ((actualValue == null) ? this.intArrayField : actualValue);
+ this.intArrayField.set($value);
}
}
}
- return (int[]) ((value == this.intArrayField) ? null : value);
+ return (int[]) (($value == this.intArrayField) ? null : $value);
}
}
diff --git a/test/transform/resource/after-ecj/GetterLazyTransient.java b/test/transform/resource/after-ecj/GetterLazyTransient.java
index 7e5f4a41..b97fe533 100644
--- a/test/transform/resource/after-ecj/GetterLazyTransient.java
+++ b/test/transform/resource/after-ecj/GetterLazyTransient.java
@@ -6,21 +6,21 @@ class GetterLazyTransient {
super();
}
public @java.lang.SuppressWarnings({"all", "unchecked"}) int getNonTransientField() {
- java.lang.Object value = this.nonTransientField.get();
- if ((value == null))
+ java.lang.Object $value = this.nonTransientField.get();
+ if (($value == null))
{
synchronized (this.nonTransientField)
{
- value = this.nonTransientField.get();
- if ((value == null))
+ $value = this.nonTransientField.get();
+ if (($value == null))
{
final int actualValue = 1;
- value = actualValue;
- this.nonTransientField.set(value);
+ $value = actualValue;
+ this.nonTransientField.set($value);
}
}
}
- return (java.lang.Integer) value;
+ return (java.lang.Integer) $value;
}
public @java.lang.SuppressWarnings("all") int getNonLazyTransientField() {
return this.nonLazyTransientField;
diff --git a/test/transform/resource/after-ecj/LockedInInitializer.java b/test/transform/resource/after-ecj/LockedInInitializer.java
new file mode 100644
index 00000000..aea88d0d
--- /dev/null
+++ b/test/transform/resource/after-ecj/LockedInInitializer.java
@@ -0,0 +1,49 @@
+import lombok.Locked;
+public class LockedInInitializer {
+ public static final Runnable LOCKED = new Runnable() {
+ private final java.util.concurrent.locks.Lock $lock = new java.util.concurrent.locks.ReentrantLock();
+ public @Override @Locked void run() {
+ this.$lock.lock();
+ try
+ {
+ System.out.println("test");
+ }
+ finally
+ {
+ this.$lock.unlock();
+ }
+ }
+ };
+ public static final Runnable LOCKED_READ = new Runnable() {
+ private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
+ public @Override @Locked.Read void run() {
+ this.$lock.readLock().lock();
+ try
+ {
+ System.out.println("test");
+ }
+ finally
+ {
+ this.$lock.readLock().unlock();
+ }
+ }
+ };
+ public static final Runnable LOCKED_WRITE = new Runnable() {
+ private final java.util.concurrent.locks.ReadWriteLock $lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
+ public @Override @Locked.Write void run() {
+ this.$lock.writeLock().lock();
+ try
+ {
+ System.out.println("test");
+ }
+ finally
+ {
+ this.$lock.writeLock().unlock();
+ }
+ }
+ };
+ () {
+ }
+ public LockedInInitializer() {
+ }
+}
diff --git a/test/transform/resource/after-ecj/SkipSuppressWarnings.java b/test/transform/resource/after-ecj/SkipSuppressWarnings.java
index 53032519..76b79fe2 100644
--- a/test/transform/resource/after-ecj/SkipSuppressWarnings.java
+++ b/test/transform/resource/after-ecj/SkipSuppressWarnings.java
@@ -8,20 +8,20 @@ class SkipSuppressWarnings {
return this.field;
}
public @java.lang.SuppressWarnings({"unchecked"}) String getField2() {
- java.lang.Object value = this.field2.get();
- if ((value == null))
+ java.lang.Object $value = this.field2.get();
+ if (($value == null))
{
synchronized (this.field2)
{
- value = this.field2.get();
- if ((value == null))
+ $value = this.field2.get();
+ if (($value == null))
{
final String actualValue = "";
- value = ((actualValue == null) ? this.field2 : actualValue);
- this.field2.set(value);
+ $value = ((actualValue == null) ? this.field2 : actualValue);
+ this.field2.set($value);
}
}
}
- return (String) ((value == this.field2) ? null : value);
+ return (String) (($value == this.field2) ? null : $value);
}
}
\ No newline at end of file
diff --git a/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java b/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java
new file mode 100644
index 00000000..2e981b02
--- /dev/null
+++ b/test/transform/resource/after-ecj/SneakyThrowsInInitializer.java
@@ -0,0 +1,19 @@
+import lombok.SneakyThrows;
+public class SneakyThrowsInInitializer {
+ public static final Runnable R = new Runnable() {
+ public @Override @SneakyThrows void run() {
+ try
+ {
+ System.out.println("test");
+ }
+ catch (final java.lang.Throwable $ex)
+ {
+ throw lombok.Lombok.sneakyThrow($ex);
+ }
+ }
+ };
+ () {
+ }
+ public SneakyThrowsInInitializer() {
+ }
+}
diff --git a/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java
new file mode 100644
index 00000000..9dea5ba0
--- /dev/null
+++ b/test/transform/resource/after-ecj/SuperBuilderWithAnnotatedTypeParam.java
@@ -0,0 +1,95 @@
+//version 8:
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+public class SuperBuilderWithAnnotatedTypeParam {
+ public @Documented @Target({ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation {
+ }
+ public static @lombok.experimental.SuperBuilder class Parent {
+ public static abstract @java.lang.SuppressWarnings("all") class ParentBuilder, B extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder> {
+ private @java.lang.SuppressWarnings("all") A field1;
+ public ParentBuilder() {
+ super();
+ }
+ /**
+ * @return {@code this}.
+ */
+ public @java.lang.SuppressWarnings("all") B field1(final A field1) {
+ this.field1 = field1;
+ return self();
+ }
+ protected abstract @java.lang.SuppressWarnings("all") B self();
+ public abstract @java.lang.SuppressWarnings("all") C build();
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (("SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder(field1=" + this.field1) + ")");
+ }
+ }
+ private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder, SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl> {
+ private ParentBuilderImpl() {
+ super();
+ }
+ protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl self() {
+ return this;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent build() {
+ return new SuperBuilderWithAnnotatedTypeParam.Parent(this);
+ }
+ }
+ A field1;
+ protected @java.lang.SuppressWarnings("all") Parent(final SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder b) {
+ super();
+ this.field1 = b.field1;
+ }
+ public static @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilder builder() {
+ return new SuperBuilderWithAnnotatedTypeParam.Parent.ParentBuilderImpl();
+ }
+ }
+ public static @lombok.experimental.SuperBuilder class Child extends Parent<@MyAnnotation String> {
+ public static abstract @java.lang.SuppressWarnings("all") class ChildBuilder> extends Parent.ParentBuilder<@MyAnnotation String, C, B> {
+ private @java.lang.SuppressWarnings("all") double field3;
+ public ChildBuilder() {
+ super();
+ }
+ /**
+ * @return {@code this}.
+ */
+ public @java.lang.SuppressWarnings("all") B field3(final double field3) {
+ this.field3 = field3;
+ return self();
+ }
+ protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self();
+ public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build();
+ public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
+ return (((("SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder(super=" + super.toString()) + ", field3=") + this.field3) + ")");
+ }
+ }
+ private static final @java.lang.SuppressWarnings("all") class ChildBuilderImpl extends SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder {
+ private ChildBuilderImpl() {
+ super();
+ }
+ protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl self() {
+ return this;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child build() {
+ return new SuperBuilderWithAnnotatedTypeParam.Child(this);
+ }
+ }
+ double field3;
+ protected @java.lang.SuppressWarnings("all") Child(final SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder, ?> b) {
+ super(b);
+ this.field3 = b.field3;
+ }
+ public static @java.lang.SuppressWarnings("all") SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilder, ?> builder() {
+ return new SuperBuilderWithAnnotatedTypeParam.Child.ChildBuilderImpl();
+ }
+ }
+ public SuperBuilderWithAnnotatedTypeParam() {
+ super();
+ }
+ public static void test() {
+ Child x = Child.builder().field3(0.0).field1("string").build();
+ }
+}
diff --git a/test/transform/resource/after-ecj/SynchronizedInInitializer.java b/test/transform/resource/after-ecj/SynchronizedInInitializer.java
new file mode 100644
index 00000000..dad6ff8d
--- /dev/null
+++ b/test/transform/resource/after-ecj/SynchronizedInInitializer.java
@@ -0,0 +1,16 @@
+import lombok.Synchronized;
+public class SynchronizedInInitializer {
+ public static final Runnable SYNCHRONIZED = new Runnable() {
+ private final java.lang.Object $lock = new java.lang.Object[0];
+ public @Override @Synchronized void run() {
+ synchronized (this.$lock)
+ {
+ System.out.println("test");
+ }
+ }
+ };
+ () {
+ }
+ public SynchronizedInInitializer() {
+ }
+}
diff --git a/test/transform/resource/after-ecj/WithOnNestedRecord.java b/test/transform/resource/after-ecj/WithOnNestedRecord.java
new file mode 100644
index 00000000..a83ac94c
--- /dev/null
+++ b/test/transform/resource/after-ecj/WithOnNestedRecord.java
@@ -0,0 +1,20 @@
+import lombok.With;
+public record WithOnNestedRecord() {
+ public @With record Nested(String a, String b) {
+/* Implicit */ private final String a;
+/* Implicit */ private final String b;
+
+ /**
+ * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
+ */
+ public @java.lang.SuppressWarnings("all") WithOnNestedRecord.Nested withA(final String a) {
+ return ((this.a == a) ? this : new WithOnNestedRecord.Nested(a, this.b));
+ }
+ /**
+ * @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
+ */
+ public @java.lang.SuppressWarnings("all") WithOnNestedRecord.Nested withB(final String b) {
+ return ((this.b == b) ? this : new WithOnNestedRecord.Nested(this.a, b));
+ }
+ }
+}
diff --git a/test/transform/resource/before/BuilderOnNestedClass.java b/test/transform/resource/before/BuilderOnNestedClass.java
new file mode 100644
index 00000000..741ac520
--- /dev/null
+++ b/test/transform/resource/before/BuilderOnNestedClass.java
@@ -0,0 +1,8 @@
+public class BuilderOnNestedClass {
+ private T t;
+
+ @lombok.Builder
+ public static class Nested {
+ private String a;
+ }
+}
diff --git a/test/transform/resource/before/BuilderOnNestedRecord.java b/test/transform/resource/before/BuilderOnNestedRecord.java
new file mode 100644
index 00000000..18a99962
--- /dev/null
+++ b/test/transform/resource/before/BuilderOnNestedRecord.java
@@ -0,0 +1,7 @@
+// version 14:
+public record BuilderOnNestedRecord(T t) {
+ @lombok.Builder
+ public record Nested(String a) {
+
+ }
+}
diff --git a/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java b/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java
new file mode 100644
index 00000000..65c08404
--- /dev/null
+++ b/test/transform/resource/before/ExtensionMethodAmbiguousFunctional.java
@@ -0,0 +1,20 @@
+//version 8:
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import lombok.experimental.ExtensionMethod;
+
+@ExtensionMethod({ExtensionMethodAmbiguousFunctional.Extensions.class})
+class ExtensionMethodAmbiguousFunctional {
+ public void test() {
+ "".ambiguous(System.out::println);
+ }
+
+ static class Extensions {
+ public static void ambiguous(T t, Function function) {
+ }
+
+ public static void ambiguous(T t, Consumer function) {
+ }
+ }
+}
diff --git a/test/transform/resource/before/LockedInInitializer.java b/test/transform/resource/before/LockedInInitializer.java
new file mode 100644
index 00000000..f4df0247
--- /dev/null
+++ b/test/transform/resource/before/LockedInInitializer.java
@@ -0,0 +1,26 @@
+//eclipse: verify diet
+import lombok.Locked;
+
+public class LockedInInitializer {
+ public static final Runnable LOCKED = new Runnable() {
+ @Override
+ @Locked
+ public void run() {
+ System.out.println("test");
+ }
+ };
+ public static final Runnable LOCKED_READ = new Runnable() {
+ @Override
+ @Locked.Read
+ public void run() {
+ System.out.println("test");
+ }
+ };
+ public static final Runnable LOCKED_WRITE = new Runnable() {
+ @Override
+ @Locked.Write
+ public void run() {
+ System.out.println("test");
+ }
+ };
+}
\ No newline at end of file
diff --git a/test/transform/resource/before/RecordNonNull b/test/transform/resource/before/RecordNonNull
deleted file mode 100644
index e69de29b..00000000
diff --git a/test/transform/resource/before/SneakyThrowsInInitializer.java b/test/transform/resource/before/SneakyThrowsInInitializer.java
new file mode 100644
index 00000000..87f77309
--- /dev/null
+++ b/test/transform/resource/before/SneakyThrowsInInitializer.java
@@ -0,0 +1,15 @@
+//eclipse: verify diet
+import lombok.SneakyThrows;
+
+public class SneakyThrowsInInitializer {
+
+ public static final Runnable R = new Runnable() {
+
+ @Override
+ @SneakyThrows
+ public void run() {
+ System.out.println("test");
+
+ }
+ };
+}
diff --git a/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java
new file mode 100644
index 00000000..4f5bed50
--- /dev/null
+++ b/test/transform/resource/before/SuperBuilderWithAnnotatedTypeParam.java
@@ -0,0 +1,29 @@
+//version 8:
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+
+public class SuperBuilderWithAnnotatedTypeParam {
+ @Documented
+ @Target( { ElementType.TYPE_USE, ElementType.ANNOTATION_TYPE })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface MyAnnotation {
+ }
+
+ @lombok.experimental.SuperBuilder
+ public static class Parent {
+ A field1;
+ }
+
+ @lombok.experimental.SuperBuilder
+ public static class Child extends Parent<@MyAnnotation String> {
+ double field3;
+ }
+
+ public static void test() {
+ Child x = Child.builder().field3(0.0).field1("string").build();
+ }
+}
diff --git a/test/transform/resource/before/SynchronizedInInitializer.java b/test/transform/resource/before/SynchronizedInInitializer.java
new file mode 100644
index 00000000..4d295d9e
--- /dev/null
+++ b/test/transform/resource/before/SynchronizedInInitializer.java
@@ -0,0 +1,12 @@
+//eclipse: verify diet
+import lombok.Synchronized;
+
+public class SynchronizedInInitializer {
+ public static final Runnable SYNCHRONIZED = new Runnable() {
+ @Override
+ @Synchronized
+ public void run() {
+ System.out.println("test");
+ }
+ };
+}
\ No newline at end of file
diff --git a/test/transform/resource/before/WithOnNestedRecord.java b/test/transform/resource/before/WithOnNestedRecord.java
new file mode 100644
index 00000000..d8d28f35
--- /dev/null
+++ b/test/transform/resource/before/WithOnNestedRecord.java
@@ -0,0 +1,9 @@
+// version 14:
+import lombok.With;
+
+public record WithOnNestedRecord() {
+ @With
+ public record Nested(String a, String b) {
+
+ }
+}
\ No newline at end of file
diff --git a/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages b/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages
new file mode 100644
index 00000000..9fa3414f
--- /dev/null
+++ b/test/transform/resource/messages-delombok/ExtensionMethodAmbiguousFunctional.java.messages
@@ -0,0 +1 @@
+9 reference to ambiguous is ambiguous both method ambiguous(T,java.util.function.Function) in ExtensionMethodAmbiguousFunctional.Extensions and method ambiguous(T,java.util.function.Consumer) in ExtensionMethodAmbiguousFunctional.Extensions match
diff --git a/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages b/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages
new file mode 100644
index 00000000..63e76c93
--- /dev/null
+++ b/test/transform/resource/messages-ecj/ExtensionMethodAmbiguousFunctional.java.messages
@@ -0,0 +1 @@
+10 The method ambiguous(String, Function) is ambiguous for the type ExtensionMethodAmbiguousFunctional.Extensions
diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html
index 1461161f..05881083 100644
--- a/website/templates/features/Builder.html
+++ b/website/templates/features/Builder.html
@@ -66,7 +66,7 @@
Now that the "method" mode is clear, putting a @Builder annotation on a constructor functions similarly; effectively, constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their type parameters are the same as the type parameters of the class itself.
- Finally, applying @Builder to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the @Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself. 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").
@@ -100,7 +100,8 @@
If a certain field/parameter is never set during a build session, then it always gets 0 / null / false. If you've put @Builder on a class (and not a method or constructor) you can instead specify the default directly on the field, and annotate the field with @Builder.Default:
- @Builder.Default private final long created = System.currentTimeMillis();
+ @Builder.Default private final long created = System.currentTimeMillis();
+ Calling Lombok-generated constructors such as @NoArgsConstructor will also make use of the defaults specified using @Builder.Default however explicit constructors will no longer use the default values and will need to be set manually or call a Lombok-generated constructor such as this(); to set the defaults.
@f.featureSection>
diff --git a/website/templates/features/GetterSetter.html b/website/templates/features/GetterSetter.html
index 8b16d34d..8cf25ee4 100644
--- a/website/templates/features/GetterSetter.html
+++ b/website/templates/features/GetterSetter.html
@@ -28,7 +28,7 @@
lombok.accessors.fluent = [true | false] (default: false)
- If set to true, generated getters and setters will not be prefixed with the bean-standard 'get, is or set; instead, the methods will use the same name as the field (minus prefixes). An explicitly configured chain parameter of an @Accessors annotation takes precedence over this setting.
+ If set to true, generated getters and setters will not be prefixed with the bean-standard 'get, is or set; instead, the methods will use the same name as the field (minus prefixes). An explicitly configured fluent parameter of an @Accessors annotation takes precedence over this setting.
lombok.accessors.prefix += a field prefix (default: empty list)
diff --git a/website/templates/features/Locked.html b/website/templates/features/Locked.html
index 105bf6dc..fa041975 100644
--- a/website/templates/features/Locked.html
+++ b/website/templates/features/Locked.html
@@ -1,4 +1,4 @@
-<#import "../_features.html" as f>
+<#import "_features.html" as f>
<@f.scaffold title="@Locked" logline="Pop it and lock it! ReentrantLock, now with less hassle.">
<@f.history>
diff --git a/website/usageExamples/experimental/LockedExample_post.jpage b/website/usageExamples/LockedExample_post.jpage
similarity index 100%
rename from website/usageExamples/experimental/LockedExample_post.jpage
rename to website/usageExamples/LockedExample_post.jpage
diff --git a/website/usageExamples/experimental/LockedExample_pre.jpage b/website/usageExamples/LockedExample_pre.jpage
similarity index 100%
rename from website/usageExamples/experimental/LockedExample_pre.jpage
rename to website/usageExamples/LockedExample_pre.jpage