diff options
-rw-r--r-- | buildScripts/build-support.ant.xml | 2 | ||||
-rw-r--r-- | buildScripts/compile.ant.xml | 113 | ||||
-rw-r--r-- | buildScripts/mapstructBinding.ant.xml | 46 | ||||
-rw-r--r-- | buildScripts/maven.ant.xml | 2 | ||||
-rw-r--r-- | buildScripts/setup.ant.xml | 34 | ||||
-rw-r--r-- | buildScripts/tests.ant.xml | 14 | ||||
-rw-r--r-- | buildScripts/website.ant.xml | 2 | ||||
-rw-r--r-- | doc/changelog.markdown | 1 | ||||
-rw-r--r-- | src/core/lombok/core/PostCompiler.java | 10 | ||||
-rw-r--r-- | src/core/lombok/javac/JavacAST.java | 9 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleBuilder.java | 2 | ||||
-rw-r--r-- | src/core9/module-info.java | 2 | ||||
-rw-r--r-- | src/utils/lombok/permit/Permit.java | 23 | ||||
-rw-r--r-- | test/transform/resource/after-delombok/BuilderWithToBuilder.java | 48 | ||||
-rw-r--r-- | test/transform/resource/after-ecj/BuilderWithToBuilder.java | 32 | ||||
-rw-r--r-- | test/transform/resource/before/BuilderWithToBuilder.java | 13 | ||||
-rw-r--r-- | website/templates/features/EqualsAndHashCode.html | 2 |
17 files changed, 276 insertions, 79 deletions
diff --git a/buildScripts/build-support.ant.xml b/buildScripts/build-support.ant.xml index 107f5f47..d6439cb0 100644 --- a/buildScripts/build-support.ant.xml +++ b/buildScripts/build-support.ant.xml @@ -50,7 +50,7 @@ None of these tasks are normally needed, unless modifying how the build works, s <input addproperty="target.jdk">You need to specify the JDK9+ jdk whose jdk.compiler and java.compiler modules are to be converted. Run ant with -Dtarget.jdk=/full/path/here to automate this, or type the path in now (for example: /Library/JavaVirtualMachines/jdk-14.jdk/Contents/Home):</input> </target> - <target name="make.javac-patch-jar" depends="-ask.target-jdk" description="to test javac13 on JDK14, for example, you need a jar (not a jmod), to use with --patch-modules. This task makes those."> + <target name="make.javac-patch-jar" depends="-ask.target-jdk, -setup.build" description="to test javac13 on JDK14, for example, you need a jar (not a jmod), to use with --patch-modules. This task makes those."> <exec executable="${target.jdk}/bin/java${executable.suffix}" outputproperty="target.javac.version.full" errorproperty="target.javac.version.err"> <arg value="--version" /> </exec> diff --git a/buildScripts/compile.ant.xml b/buildScripts/compile.ant.xml index 5baf50c3..54017496 100644 --- a/buildScripts/compile.ant.xml +++ b/buildScripts/compile.ant.xml @@ -24,19 +24,18 @@ This buildfile is part of projectlombok.org. It takes care of compiling and building lombok itself. </description> - <property name="mapstruct-binding.version" value="0.1.0" /> + <property name="mapstruct-binding.version" value="0.2.0" /> <!-- compiles just 'version.java' and runs the produced class file, setting up the various version properties --> - <target name="version" depends="ipp.setup, deps.jdk-runtime" description="Shows the version number" unless="lombok.version"> - <mkdir dir="build/lombok" /> - <ivy:compile destdir="build/lombok" source="1.5" target="1.5" ecj="true" nowarn="true"> + <target name="version" depends="ipp.setup, deps.jdk-runtime, -setup.build" description="Shows the version number" unless="lombok.version"> + <ivy:compile destdir="build/lombok-version" source="1.5" target="1.5" ecj="true" nowarn="true"> <bootclasspath path="${jdk6-rt.loc}" /> <src path="src/core" /> <include name="lombok/core/Version.java" /> </ivy:compile> <java classname="lombok.core.Version" - classpath="build/lombok" + classpath="build/lombok-version" failonerror="true" output="build/version.txt"> <arg value="full" /> @@ -44,18 +43,30 @@ This buildfile is part of projectlombok.org. It takes care of compiling and buil <ivy:loadversion property="lombok.fullversion" file="build/version.txt" /> <java classname="lombok.core.Version" - classpath="build/lombok" + classpath="build/lombok-version" failonerror="true" output="build/version.txt" /> <ivy:loadversion property="lombok.version" file="build/version.txt" /> <echo level="info">Lombok version: ${lombok.version} (${lombok.fullversion})</echo> </target> - <target name="compile" depends="version, deps" description="Compiles the code"> + <property name="packing.basedirs" value="build/lombok-transplants,build/lombok-utils,build/lombok-utils6,build/lombok-main,build/lombok-main8,build/lombok-meta,build/lombok-deps" /> + <loadresource property="packing.basedirs.colon"> + <propertyresource name="packing.basedirs" /> + <filterchain><tokenfilter> + <filetokenizer/> + <replacestring from="," to=":" /> + </tokenfilter></filterchain> + </loadresource> + <path id="packing.basedirs.path"> + <pathelement path="${packing.basedirs.colon}" /> + </path> + + <target name="compile" depends="version, deps, -setup.build" description="Compiles the code"> <!-- 1. Compile stubs. - 2. Compile lombok-utils. - 3. Compile transplants. + 2. Compile transplants. + 3. Compile lombok-utils. 4. Compile lombok. 5. Run SPI processor. 6. Create other manifest entries. --> @@ -65,7 +76,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and buil the bleeding edge lombok from the previous build is run (as lombok is an annotation processor), which means if there are bugs in it, you can't compile anymore until you 'ant clean'. That's very undesirable. so we kill the processor, which stops lombok from running. We re-create the file at the end of this target. --> - <delete file="build/lombok/META-INF/services/javax.annotation.processing.Processor" quiet="true" /> + <delete file="build/lombok-meta/META-INF/services/javax.annotation.processing.Processor" quiet="true" /> <!-- first, compile stubs. Lombok needs to produce class files that run in a wide variety of JDK, javac, and ecj/eclipse versions. @@ -106,40 +117,40 @@ This buildfile is part of projectlombok.org. It takes care of compiling and buil </filterchain> </copy> - <ivy:compile destdir="build/lombok" source="1.4" target="1.4" ecj="true"> + <ivy:compile destdir="build/lombok-transplants" source="1.4" target="1.4" ecj="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="build/transformedSources" /> </ivy:compile> - <ivy:compile destdir="build/lombok/Class50" source="1.4" target="1.6" ecj="true"> + <ivy:compile destdir="build/lombok-transplants/Class50" source="1.4" target="1.6" ecj="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="build/transformedSources" /> </ivy:compile> - <ivy:compile destdir="build/lombok" source="1.5" target="1.5" ecj="true"> + <ivy:compile destdir="build/lombok-utils" source="1.5" target="1.5" ecj="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="src/utils" /> <exclude name="lombok/javac/**" /> - <classpath path="build/lombok" /> + <classpath location="build/lombok-utils" /> <classpath refid="cp.javac6" /> <classpath refid="cp.ecj8" /> </ivy:compile> - <ivy:compile destdir="build/lombok" source="1.6" target="1.6" ecj="true"> + <ivy:compile destdir="build/lombok-utils6" source="1.6" target="1.6" ecj="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="src/utils" /> <include name="lombok/javac/**" /> - <classpath location="build/lombok" /> <classpath refid="cp.javac6" /> + <classpath path="build/lombok-utils:build/lombok-utils6" /> </ivy:compile> <!-- compile lombok proper. We target java 1.6 to be as compatible with older releases as we can, using a JDK6 boot rt to ensure we don't use API that didn't exist in those versions yet. --> - <ivy:compile destdir="build/lombok" source="1.6" target="1.6" ecj="true" nowarn="true"> + <ivy:compile destdir="build/lombok-main" source="1.6" target="1.6" ecj="true" nowarn="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="src/launch" /> @@ -148,40 +159,39 @@ This buildfile is part of projectlombok.org. It takes care of compiling and buil <src path="src/eclipseAgent" /> <src path="src/delombok" /> <exclude name="**/*Transplants.java" /> - <classpath location="build/lombok" /> <classpath refid="cp.build" /> <classpath refid="cp.eclipse-oxygen" /> <classpath refid="cp.javac6" /> + <classpath path="build/lombok-utils:build/lombok-utils6:build/lombok-main" /> </ivy:compile> <!-- This is really part of the eclipse agent, but references lombok, so that had to be compiled first --> - <ivy:compile destdir="build/lombok/Class50" source="1.5" target="1.6" ecj="true"> + <ivy:compile destdir="build/lombok-main/Class50" source="1.5" target="1.6" ecj="true"> <bootclasspath location="build/stubs" /> <bootclasspath path="${jdk6-rt.loc}" /> <src path="src/eclipseAgent" /> <include name="lombok/launch/PatchFixesHider.java" /> - <classpath location="build/lombok" /> <classpath refid="cp.build" /> <classpath refid="cp.eclipse-oxygen" /> + <classpath path="build/lombok-utils:build/lombok-utils6:build/lombok-main" /> </ivy:compile> <!-- a couple of classes to cater to the bits of javac8+ that require j8 language constructs/API types; the main lombok compile refers to these via reflection --> - <ivy:compile destdir="build/lombok" source="1.8" target="1.8" ecj="true" nowarn="true" includesystembootclasspath="true"> + <ivy:compile destdir="build/lombok-main8" source="1.8" target="1.8" ecj="true" nowarn="true" includesystembootclasspath="true"> <bootclasspath location="build/stubs" /> <src path="src/core8" /> - <classpath location="build/lombok" /> <classpath refid="cp.javac8" /> + <classpath path="build/lombok-main:build/lombok-main8" /> </ivy:compile> <!-- We also act as a jigsaw module so that module-based compile runs can use module-style dependency management. Obviously, that bit we can only compile with jdk9+. --> - <ivy:compile destdir="build/lombok" release="9"> + <ivy:compile destdir="build/lombok-main" release="9"> <src path="src/core9" /> <compilerarg value="-Xlint:none" /> - <classpath location="build/lombok" /> <classpath refid="cp.build" /> </ivy:compile> @@ -196,41 +206,39 @@ This buildfile is part of projectlombok.org. It takes care of compiling and buil <src path="src/installer" /> <src path="src/eclipseAgent" /> <src path="src/delombok" /> - <classpath location="build/lombok" /> <classpath refid="cp.build" /> <classpath refid="cp.javac6" /> <classpath refid="cp.eclipse-oxygen" /> + <classpath path="build/lombok-utils:build/lombok-utils6:build/lombok-main" /> </ivy:compile> - <copy todir="build/lombok"> + <mkdir dir="build/lombok-meta" /> + + <copy todir="build/lombok-meta"> <fileset dir="build/lombok-proc-result"> <include name="META-INF/services/*" /> </fileset> </copy> - <mkdir dir="build/lombok/META-INF" /> - <mkdir dir="build/lombok/META-INF/services" /> - <echo file="build/lombok/META-INF/services/javax.annotation.processing.Processor">lombok.launch.AnnotationProcessorHider$AnnotationProcessor + <mkdir dir="build/lombok-meta/META-INF" /> + <mkdir dir="build/lombok-meta/META-INF/services" /> + <echo file="build/lombok-meta/META-INF/services/javax.annotation.processing.Processor">lombok.launch.AnnotationProcessorHider$AnnotationProcessor lombok.launch.AnnotationProcessorHider$ClaimingProcessor</echo> - <mkdir dir="build/lombok/META-INF/gradle" /> - <echo file="build/lombok/META-INF/gradle/incremental.annotation.processors">lombok.launch.AnnotationProcessorHider$AnnotationProcessor,isolating + <mkdir dir="build/lombok-meta/META-INF/gradle" /> + <echo file="build/lombok-meta/META-INF/gradle/incremental.annotation.processors">lombok.launch.AnnotationProcessorHider$AnnotationProcessor,isolating lombok.launch.AnnotationProcessorHider$ClaimingProcessor,isolating</echo> </target> <!-- compiles the bit of API from mapstruct that lombok compiles against. --> - <target name="mapstruct.compile"> + <target name="mapstruct.compile" depends="-setup.build"> <mkdir dir="build/mapstruct" /> - <ivy:compile destdir="build/mapstruct" release="9"> + <ivy:compile destdir="build/mapstruct" release="8"> <src path="src/j9stubs" /> </ivy:compile> - <mkdir dir="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi" /> - <move - file="build/mapstruct/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.class" - tofile="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.SCL.lombok" /> </target> <target name="-deps.unpack" depends="deps"> - <ivy:cachedunjar dest="build/lombok" marker="build/unpackDeps.marker"> + <ivy:cachedunjar dest="build/lombok-deps" marker="build/unpackDeps.marker"> <path refid="cp.stripe" /> </ivy:cachedunjar> </target> @@ -252,7 +260,7 @@ lombok.launch.AnnotationProcessorHider$ClaimingProcessor,isolating</echo> lombok classes served up in autocomplete dialogs, amongst other reasons. Thus, we list here only the few class files that serve as 'entry points'. --> - <fileset dir="build/lombok"> + <patternset id="packing.entrypoints"> <include name="module-info.class" /> <include name="lombok/*.class" /> <include name="lombok/experimental/**" /> @@ -261,21 +269,20 @@ lombok.launch.AnnotationProcessorHider$ClaimingProcessor,isolating</echo> <include name="lombok/delombok/ant/Tasks*" /> <include name="lombok/javac/apt/Processor.class" /> <include name="lombok/META-INF/**" /> - </fileset> + </patternset> + + <fileset dir="build/lombok-main"><patternset refid="packing.entrypoints" /></fileset> + <fileset dir="build/lombok-meta"><patternset refid="packing.entrypoints" /></fileset> - <!-- now include everything else but renamed for the shadowloader system, to make these clsases invisible to other projects. --> + <!-- now include everything else but renamed for the shadowloader system, to make these classes invisible to other projects. --> + <patternset id="packing.shadowed"> + <exclude name="com/sun/tools/javac/**" /> + <invert><patternset refid="packing.entrypoints" /></invert> + </patternset> <mappedresources> - <fileset dir="build/lombok"> - <exclude name="com/sun/tools/javac/**" /> - <exclude name="module-info.class" /> - <exclude name="lombok/*.class" /> - <exclude name="lombok/experimental/**" /> - <exclude name="lombok/extern/**" /> - <exclude name="lombok/launch/**" /> - <exclude name="lombok/delombok/ant/Tasks*" /> - <exclude name="lombok/javac/apt/Processor.class" /> - <exclude name="lombok/META-INF/**" /> - </fileset> + <multirootfileset basedirs="${packing.basedirs}"> + <patternset refid="packing.shadowed" /> + </multirootfileset> <firstmatchmapper> <globmapper from="*.class" to="*.SCL.lombok" /> <identitymapper /> @@ -298,7 +305,7 @@ lombok.launch.AnnotationProcessorHider$ClaimingProcessor,isolating</echo> <property name="lombok.dist.built" value="true" /> </target> - <target name="compile.support" depends="ipp.setup, deps" description="Compiles code that is used solely by the build, such as website and IDE project creation"> + <target name="compile.support" depends="ipp.setup, deps, -setup.build" description="Compiles code that is used solely by the build, such as website and IDE project creation"> <ivy:compile includeDestClasses="false" includeantruntime="false" destdir="build/support" debug="on" source="1.8" target="1.8"> <compilerarg value="-proc:none" /> <compilerarg value="-Xlint:-options" /> diff --git a/buildScripts/mapstructBinding.ant.xml b/buildScripts/mapstructBinding.ant.xml index c59b84da..d7c52dc3 100644 --- a/buildScripts/mapstructBinding.ant.xml +++ b/buildScripts/mapstructBinding.ant.xml @@ -26,14 +26,11 @@ version on mavencentral is the last version that is ever needed; the code itself exists as a separate dependency solely because it is itself dependent on both lombok and mapstruct. </description> - <target name="-mapstructBinding.compile"> + <target name="-mapstructBinding.compile" depends="-setup.build"> <mkdir dir="build/mapstruct" /> - <javac includeAntRuntime="false" source="1.9" target="1.9" destdir="build/mapstruct"> + <javac includeAntRuntime="false" source="1.8" target="1.8" destdir="build/mapstruct"> <src path="src/j9stubs" /> - <!-- This includes org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; putting this on the classpath doesn't work (needs to be internal or a module) so we just add it and then delete the class file for convenience. --> </javac> - <mkdir dir="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi" /> - <move file="build/mapstruct/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.class" tofile="build/lombok/secondaryLoading.SCL.lombok/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.SCL.lombok" /> </target> <target name="-mapstructBinding.prepare" depends="-mapstructBinding.compile"> @@ -76,12 +73,18 @@ exists as a separate dependency solely because it is itself dependent on both lo <jar destfile="dist/lombok-mapstruct-binding-${mapstruct-binding.version}-javadoc.jar" basedir="build/mapstruct-binding/api" includes="**" /> </target> - <target name="-mapstructBinding.jar" depends="dist,-mapstructBinding.prepare"> + <target name="-mapstructBinding.jar" depends="dist, -mapstructBinding.prepare"> <mkdir dir="build/mapstruct-binding/classes" /> <echo file="build/mapstruct-binding/classes/META-INF/services/org.mapstruct.ap.spi.AstModifyingAnnotationProcessor">lombok.mapstruct.NotifierHider$AstModificationNotifier</echo> + <javac includeAntRuntime="false" source="1.8" target="1.8" destdir="build/mapstruct-binding/classes"> + <src path="src/bindings/mapstruct" /> + <exclude name="module-info.java" /> + <classpath location="build/mapstruct" /> + </javac> <javac includeAntRuntime="false" source="1.9" target="1.9" destdir="build/mapstruct-binding/classes" modulepath="build/mapstruct-module-path"> <src path="src/bindings/mapstruct" /> + <include name="module-info.java" /> </javac> <jar destfile="dist/lombok-mapstruct-binding-${mapstruct-binding.version}.jar" basedir="build/mapstruct-binding/classes" includes="**" /> </target> @@ -93,6 +96,37 @@ exists as a separate dependency solely because it is itself dependent on both lo <target name="mapstructBinding.pack" depends="dist,-mapstructBinding.jar,-mapstructBinding.doc,-mapstructBinding.src"> </target> + <target name="mapstructBinding.publish" depends="mapstructBinding.pack, setup.ssh"> + <tar destfile="dist/mavenPublish-mapstructBinding.tar.bz2" compression="bzip2"> + <tarfileset dir="dist"> + <include name="lombok-mapstruct-binding-${mapstruct-binding.version}.jar" /> + <include name="lombok-mapstruct-binding-${mapstruct-binding.version}-sources.jar" /> + <include name="lombok-mapstruct-binding-${mapstruct-binding.version}-javadoc.jar" /> + </tarfileset> + <tarfileset dir="build/mapstruct-binding/maven" includes="pom.xml" /> + </tar> + <ivy:scpUpload + from="dist/mavenPublish-mapstructBinding.tar.bz2" + to="/data/lombok/staging" + server="projectlombok.org" + username="${ssh.username}" + keyfile="${ssh.keyfile}" + knownHosts="ssh.knownHosts" /> + <ivy:sshExec + cmd="/data/lombok/stagingCmd/publishToMavenCentral-mapstructBinding" + server="projectlombok.org" + username="${ssh.username}" + keyfile="${ssh.keyfile}" + knownHosts="ssh.knownHosts" /> + <echo>The artifact has been published to staging. Now go to https://oss.sonatype.org/ and log in as Reinier, then doublecheck if all is well and 'release' it.</echo> + <ivy:sshExec + cmd="/data/lombok/stagingCmd/showMavenCentralPassword" + server="projectlombok.org" + username="${ssh.username}" + keyfile="${ssh.keyfile}" + knownHosts="ssh.knownHosts" /> + </target> + <target name="mapstructBinding.maven" depends="mapstructBinding.pack" description="Create a maven repo for mapstruct binding into a build dir."> <delete quiet="true" dir="build/mapstruct-binding-maven" /> <mkdir dir="build/mapstruct-binding-maven" /> diff --git a/buildScripts/maven.ant.xml b/buildScripts/maven.ant.xml index dcba2ccb..57bb6b99 100644 --- a/buildScripts/maven.ant.xml +++ b/buildScripts/maven.ant.xml @@ -59,7 +59,7 @@ This buildfile is part of projectlombok.org. It makes maven-compatible repositor </sequential> </macrodef> - <target name="maven" depends="version, dist, javadoc.build" description="Creates a maven repo for the current release into a build dir. The intent is for you to put that on a server someplace. Will invoke your local mvn installation."> + <target name="maven" depends="version, dist, javadoc.build, -setup.build" description="Creates a maven repo for the current release into a build dir. The intent is for you to put that on a server someplace. Will invoke your local mvn installation."> <mkdir dir="build" /> <mkdir dir="dist" /> diff --git a/buildScripts/setup.ant.xml b/buildScripts/setup.ant.xml index ed835960..e71f8143 100644 --- a/buildScripts/setup.ant.xml +++ b/buildScripts/setup.ant.xml @@ -24,6 +24,9 @@ This buildfile is part of projectlombok.org. It sets up the build itself. </description> + <!-- increment this number to force a clean of the 'build' dir --> + <property name="build.version" value="2020-12-04_001" /> + <property name="pattern.jdk11plus" value="^(\d\d\d+|1[1-9]|[2-9]\d)(\..*)?$" /> <property name="ivy.retrieve.pattern" value="lib/[conf]/[organisation]-[artifact].[ext]" /> <property environment="env" /> @@ -84,6 +87,37 @@ This buildfile is part of projectlombok.org. It sets up the build itself. <target name="setup.ssh" depends="-setup.ssh.ask, -setup.ssh.save" /> + <target name="-autoclean.check"> + <available type="dir" file="build" property="existingbuild.present" /> + <loadresource property="existingbuild.ver"> + <first count="1"> + <resources> + <restrict> + <fileset dir="." includes="build/build-ver.txt" /> + <exists /> + </restrict> + <string>0</string> + </resources> + </first> + </loadresource> + <condition property="existingbuild.mismatch"> + <and> + <isset property="existingbuild.present" /> + <not><equals arg1="${existingbuild.ver}" arg2="${build.version}" trim="true" /></not> + </and> + </condition> + </target> + + <target name="autoclean" depends="-autoclean.check" if="existingbuild.mismatch" description="Checks if a change in the build or deplist neccessitates a clean"> + <echo>build ver has been incremented, neccessitating a clean...</echo> + <delete dir="build" /> + </target> + + <target name="-setup.build" depends="autoclean"> + <mkdir dir="build" /> + <echo file="build/build-ver.txt">${build.version}</echo> + </target> + <target name="clean" description="Removes all generated files."> <delete dir="build" quiet="true" /> </target> diff --git a/buildScripts/tests.ant.xml b/buildScripts/tests.ant.xml index cb840048..41bfa391 100644 --- a/buildScripts/tests.ant.xml +++ b/buildScripts/tests.ant.xml @@ -33,8 +33,8 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <bootclasspath path="${jdk6-rt.loc}" /> <classpath refid="cp.test" /> <classpath refid="cp.eclipse-oxygen" /> - <classpath location="build/lombok" /> - <classpath location="build/tests" /> + <classpath refid="packing.basedirs.path" /> + <classpath path="build/tests" /> <src path="test/core/src" /> <src path="test/transform/src" /> <src path="test/bytecode/src" /> @@ -84,7 +84,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <classpath refid="cp.test" /> <classpath refid="cp.stripe" /> <classpath refid="cp.javac6" /> - <classpath location="build/lombok" /> + <classpath refid="packing.basedirs.path" /> <classpath location="build/tests" /> <test name="lombok.TestJavac" /> </junit> @@ -100,7 +100,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <classpath refid="cp.test" /> <classpath refid="cp.stripe" /> <classpath refid="cp.javac8" /> - <classpath location="build/lombok" /> + <classpath refid="packing.basedirs.path" /> <classpath location="build/tests" /> <test name="lombok.TestJavac" /> </junit> @@ -117,7 +117,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <formatter type="plain" usefile="false" unless="tests.quiet" /> <classpath refid="cp.test" /> <classpath refid="cp.stripe" /> - <classpath location="build/lombok" /> + <classpath refid="packing.basedirs.path" /> <classpath location="build/tests" /> <classpath location="build/teststubs" /> <test name="lombok.TestJavac" /> @@ -140,7 +140,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <formatter type="plain" usefile="false" unless="tests.quiet" /> <classpath refid="cp.test" /> <classpath refid="cp.stripe" /> - <classpath location="build/lombok" /> + <classpath refid="packing.basedirs.path" /> <classpath location="build/tests" /> <classpath location="build/teststubs" /> <test name="lombok.TestJavac" /> @@ -160,7 +160,7 @@ This buildfile is part of projectlombok.org. It takes care of compiling and runn <classpath refid="cp.test" /> <classpath refid="cp.stripe" /> <classpath refid="cp.eclipse-@{version}" /> - <classpath location="build/lombok" /> + <classpath refid="packing.basedirs.path" /> <classpath location="build/tests" /> <test name="lombok.TestEclipse" /> </junit> diff --git a/buildScripts/website.ant.xml b/buildScripts/website.ant.xml index 730b79c2..63ac2e8d 100644 --- a/buildScripts/website.ant.xml +++ b/buildScripts/website.ant.xml @@ -217,7 +217,7 @@ such as applying the templates to produce the website, converting the changelog <package name="lombok" /> <package name="lombok.experimental" /> <package name="lombok.extern.*" /> - <classpath location="build/lombok" /> + <classpath location="build/lombok-main" /> <header><![CDATA[<a href='https://projectlombok.org/' target='_blank'>Lombok</a> - ]]>v${lombok.version}</header> <bottom><![CDATA[<i>Copyright © 2009-${javadoc.year} The Project Lombok Authors, licensed under the <a href='http://www.opensource.org/licenses/mit-license.php' target='_blank'>MIT licence</a>.]]></bottom> </javadoc> diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 94996503..ec3d5029 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,6 +2,7 @@ Lombok Changelog ---------------- ### v1.18.17 "Edgy Guinea Pig" +* BUGFIX: Various tools using ecj under the hood (including intellij) could cause corrupt class files to be generated. [PR #2637](https://github.com/rzwitserloot/lombok/pull/2637), [lombok-intellij-plugin issue #969](https://github.com/mplushnikov/lombok-intellij-plugin/issues/969). * BUGFIX: Netbeans would not work with 1.18.16 anymore. [Issue #2612](https://github.com/rzwitserloot/lombok/issues/2612) * PLATFORM: using `lombok.config` files when compiling with sbt 1.4 now works again. [Issue #2645](https://github.com/rzwitserloot/lombok/issues/2645) * (potential) BUGFIX: Using lombok with Maven Tycho now works. With assistance from [Rabea Gransberger](https://github.com/rgra). [Issue #285](https://github.com/rzwitserloot/lombok/issues/285) __UPDATE: This doesn't quite work yet, still investigating.__ diff --git a/src/core/lombok/core/PostCompiler.java b/src/core/lombok/core/PostCompiler.java index 72f4b3a2..122bb268 100644 --- a/src/core/lombok/core/PostCompiler.java +++ b/src/core/lombok/core/PostCompiler.java @@ -28,6 +28,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; public final class PostCompiler { private PostCompiler() {/* prevent instantiation*/}; @@ -67,8 +68,17 @@ public final class PostCompiler { public static OutputStream wrapOutputStream(final OutputStream originalStream, final String fileName, final DiagnosticsReceiver diagnostics) throws IOException { if (System.getProperty("lombok.disablePostCompiler", null) != null) return originalStream; + + // close() can be called more than once and should be idempotent, therefore, ensure we never transform more than once. + final AtomicBoolean closed = new AtomicBoolean(); + return new ByteArrayOutputStream() { @Override public void close() throws IOException { + if (closed.getAndSet(true)) { + originalStream.close(); + return; + } + // no need to call super byte[] original = toByteArray(); byte[] copy = null; diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index b3e8930e..f58de60f 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -174,7 +174,14 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { if (sbtMappedVirtualFileRootsField == null) return null; String encodedPath = (String) sbtMappedVirtualFilePathField.get(mappedVirtualFile); - if (!encodedPath.startsWith("${")) return null; + if (!encodedPath.startsWith("${")) { + File maybeAbsoluteFile = new File(encodedPath); + if (maybeAbsoluteFile.exists()) { + return maybeAbsoluteFile.toURI(); + } else { + return null; + } + } int idx = encodedPath.indexOf('}'); if (idx == -1) return null; String base = encodedPath.substring(2, idx); diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 1c74ce37..40b59183 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -371,7 +371,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { } List<JCTypeParameter> tpOnMethod = jmd.typarams; - List<JCTypeParameter> tpOnType = ((JCClassDecl) job.builderType.get()).typarams; + List<JCTypeParameter> tpOnType = ((JCClassDecl) job.parentType.get()).typarams; typeArgsForToBuilder = new ArrayList<Name>(); for (JCTypeParameter tp : tpOnMethod) { diff --git a/src/core9/module-info.java b/src/core9/module-info.java index b1ee2b9d..8e8bd891 100644 --- a/src/core9/module-info.java +++ b/src/core9/module-info.java @@ -27,12 +27,12 @@ module lombok { exports lombok; exports lombok.experimental; exports lombok.extern.apachecommons; + exports lombok.extern.flogger; exports lombok.extern.jackson; exports lombok.extern.java; exports lombok.extern.jbosslog; exports lombok.extern.log4j; exports lombok.extern.slf4j; - exports lombok.extern.flogger; exports lombok.launch to lombok.mapstruct; diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java index c0006559..5101e7b0 100644 --- a/src/utils/lombok/permit/Permit.java +++ b/src/utils/lombok/permit/Permit.java @@ -38,8 +38,6 @@ import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.util.List; -import lombok.Lombok; - // sunapi suppresses javac's warning about using Unsafe; 'all' suppresses eclipse's warning about the unspecified 'sunapi' key. Leave them both. // Yes, javac's definition of the word 'all' is quite contrary to what the dictionary says it means. 'all' does NOT include 'sunapi' according to javac. @SuppressWarnings({"sunapi", "all"}) @@ -223,9 +221,9 @@ public class Permit { return null; } catch (IllegalAccessException e) { handleReflectionDebug(e, initError); - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); } catch (RuntimeException e) { handleReflectionDebug(e, initError); throw e; @@ -276,12 +274,12 @@ public class Permit { return null; } catch (IllegalAccessException e) { handleReflectionDebug(e, initError); - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InstantiationException e) { handleReflectionDebug(e, initError); - throw Lombok.sneakyThrow(e); + throw sneakyThrow(e); } catch (InvocationTargetException e) { - throw Lombok.sneakyThrow(e.getCause()); + throw sneakyThrow(e.getCause()); } catch (RuntimeException e) { handleReflectionDebug(e, initError); throw e; @@ -329,4 +327,15 @@ public class Permit { initError.printStackTrace(System.err); } } + + public static RuntimeException sneakyThrow(Throwable t) { + if (t == null) throw new NullPointerException("t"); + return Permit.<RuntimeException>sneakyThrow0(t); + } + + @SuppressWarnings("unchecked") + private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T { + throw (T)t; + } + } diff --git a/test/transform/resource/after-delombok/BuilderWithToBuilder.java b/test/transform/resource/after-delombok/BuilderWithToBuilder.java index d98d09f6..3eeadcc5 100644 --- a/test/transform/resource/after-delombok/BuilderWithToBuilder.java +++ b/test/transform/resource/after-delombok/BuilderWithToBuilder.java @@ -147,4 +147,52 @@ class ConstructorWithToBuilder<T> { public ConstructorWithToBuilder.ConstructorWithToBuilderBuilder<T> toBuilder() { return new ConstructorWithToBuilder.ConstructorWithToBuilderBuilder<T>().mOne(this.mOne).baz(this.foo).bars(this.bars); } +} +class StaticMethodWithToBuilder<T> { + private T foo; + + public StaticMethodWithToBuilder(T foo) { + this.foo = foo; + } + + public static <T> StaticMethodWithToBuilder<T> of(T foo) { + return new StaticMethodWithToBuilder<T>(foo); + } + + @java.lang.SuppressWarnings("all") + public static class StaticMethodWithToBuilderBuilder<T> { + @java.lang.SuppressWarnings("all") + private T foo; + + @java.lang.SuppressWarnings("all") + StaticMethodWithToBuilderBuilder() { + } + + @java.lang.SuppressWarnings("all") + public StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> foo(final T foo) { + this.foo = foo; + return this; + } + + @java.lang.SuppressWarnings("all") + public StaticMethodWithToBuilder<T> build() { + return StaticMethodWithToBuilder.<T>of(this.foo); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder(foo=" + this.foo + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static <T> StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> builder() { + return new StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T>(); + } + + @java.lang.SuppressWarnings("all") + public StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> toBuilder() { + return new StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T>().foo(this.foo); + } }
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/BuilderWithToBuilder.java b/test/transform/resource/after-ecj/BuilderWithToBuilder.java index 72fa3721..857caa17 100644 --- a/test/transform/resource/after-ecj/BuilderWithToBuilder.java +++ b/test/transform/resource/after-ecj/BuilderWithToBuilder.java @@ -126,3 +126,35 @@ import lombok.Builder; return new ConstructorWithToBuilder.ConstructorWithToBuilderBuilder<T>().mOne(this.mOne).baz(this.foo).bars(this.bars); } } +class StaticMethodWithToBuilder<T> { + public static @java.lang.SuppressWarnings("all") class StaticMethodWithToBuilderBuilder<T> { + private @java.lang.SuppressWarnings("all") T foo; + @java.lang.SuppressWarnings("all") StaticMethodWithToBuilderBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> foo(final T foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") StaticMethodWithToBuilder<T> build() { + return StaticMethodWithToBuilder.<T>of(this.foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder(foo=" + this.foo) + ")"); + } + } + private T foo; + public StaticMethodWithToBuilder(T foo) { + super(); + this.foo = foo; + } + public static @Builder(toBuilder = true) <T>StaticMethodWithToBuilder<T> of(T foo) { + return new StaticMethodWithToBuilder<T>(foo); + } + public static @java.lang.SuppressWarnings("all") <T>StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> builder() { + return new StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T>(); + } + public @java.lang.SuppressWarnings("all") StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T> toBuilder() { + return new StaticMethodWithToBuilder.StaticMethodWithToBuilderBuilder<T>().foo(this.foo); + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/BuilderWithToBuilder.java b/test/transform/resource/before/BuilderWithToBuilder.java index 50938ab2..5b87a18f 100644 --- a/test/transform/resource/before/BuilderWithToBuilder.java +++ b/test/transform/resource/before/BuilderWithToBuilder.java @@ -18,3 +18,16 @@ class ConstructorWithToBuilder<T> { public ConstructorWithToBuilder(String mOne, @Builder.ObtainVia(field = "foo") T baz, com.google.common.collect.ImmutableList<T> bars) { } } + +class StaticMethodWithToBuilder<T> { + private T foo; + + public StaticMethodWithToBuilder(T foo) { + this.foo = foo; + } + + @Builder(toBuilder = true) + public static <T> StaticMethodWithToBuilder<T> of(T foo) { + return new StaticMethodWithToBuilder<T>(foo); + } +}
\ No newline at end of file diff --git a/website/templates/features/EqualsAndHashCode.html b/website/templates/features/EqualsAndHashCode.html index 2ea2954a..474b4ee2 100644 --- a/website/templates/features/EqualsAndHashCode.html +++ b/website/templates/features/EqualsAndHashCode.html @@ -12,6 +12,8 @@ <em>NEW in Lombok 0.10: </em>Unless your class is <code>final</code> and extends <code>java.lang.Object</code>, lombok generates a <code>canEqual</code> method which means JPA proxies can still be equal to their base class, but subclasses that add new state don't break the equals contract. The complicated reasons for why such a method is necessary are explained in this paper: <a href="https://www.artima.com/lejava/articles/equality.html">How to Write an Equality Method in Java</a>. If all classes in a hierarchy are a mix of scala case classes and classes with lombok-generated equals methods, all equality will 'just work'. If you need to write your own equals methods, you should always override <code>canEqual</code> if you change <code>equals</code> and <code>hashCode</code>. </p><p> <em>NEW in Lombok 1.14.0: </em>To put annotations on the <code>other</code> parameter of the <code>equals</code> (and, if relevant, <code>canEqual</code>) method, you can use <code>onParam=@__({@AnnotationsHere})</code>. Be careful though! This is an experimental feature. For more details see the documentation on the <a ng-click="toFeature('on-x')">onX</a> feature. + </p><p> + <em>NEW in Lombok 1.18.16: </em>The result of the generated <code>hashCode()</code> can be cached by setting <code>cacheStrategy</code> to a value other than <code>CacheStrategy.NEVER</code>. <em>Do not</em> use this if objects of the annotated class can be modified in any way that would lead to the result of <code>hashCode()</code> changing. </p> </@f.overview> |