diff options
52 files changed, 712 insertions, 132 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..52fb04f0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +custom: https://projectlombok.org/order-license-info +patreon: lombok +tidelift: maven/org.projectlombok:lombok
\ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/security_issue.md b/.github/ISSUE_TEMPLATE/security_issue.md deleted file mode 100644 index 44033bc0..00000000 --- a/.github/ISSUE_TEMPLATE/security_issue.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: Security issue with lombok -about: Let us know about a security vulnerability in lombok -title: '[DO NOT POST HERE]' -labels: '' -assignees: '' - ---- - -***Please do not report this here!*** - -github issues are public. Please contact us privately so that we can work together to coordinate a fix for the vulnerability together with making the vulnerability public. - -You can inform the [Tidelift security contact](https://tidelift.com/security) or if you prefer, contact the core contributors of Project Lombok directly by emailing `info@projectlombok.org` @@ -7,4 +7,6 @@ Looking for professional support of Project Lombok? Lombok is now part of a tide For a list of all authors, see the AUTHORS file. -For complete project information, see https://projectlombok.org/
\ No newline at end of file +For complete project information, see https://projectlombok.org/ + +You can review our security policy via SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..43745e86 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +#Security Policies and Procedures + +Lombok only runs during compilation and is not required on your servers or in your application's distribution. Nevertheless, the _Project Lombok_ team and community take all security bugs seriously. + +## Reporting a Bug + +To report a security vulnerability, please follow the procedure described in the [Tidelift security policy](https://tidelift.com/docs/security?utm_source=lombok&utm_medium=referral&utm_campaign=github). + +Alternatively, you can send us an email privately via `info@projectlombok.org`. + +## Disclosure Policy + +When we receive a security bug report, it will be assigned a primary handler. This person will coordinate the fix and release process. In case this process requires additional resources beyond the scope of what the core contributors of _Project Lombok_ can reasonably supply, we will inform the Tidelift security team for additional help and coordination. This process will involve the following steps: + +* Inventorize all affected versions along with the platform(s) that lombok runs on which are affected. +* Audit code to find any potential similar problems. +* Prepare fixes for all releases, push these out to all distribution channels including the maven central repo, and put in all due effort to get affected versions marked as affected. + +## Comments on this Policy + +Any comments on this policy or suggestions for improvement can be discussed on [our forum](https://groups.google.com/forum/#!forum/project-lombok), or you can send us an email for any comments or suggestions that contain sensitive information. diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 9163b305..e486a713 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -3,14 +3,21 @@ Lombok Changelog ### v1.18.9 "Edgy Guinea Pig" * FEATURE: You can now configure a custom logger framework using the new `@CustomLog` annotation in combination with the `lombok.log.custom.declaration` configuration key. See the [log documentation](https://projectlombok.org/features/Log) for more information. [Pullrequest #2086](https://github.com/rzwitserloot/lombok/pull/2086) with thanks to Adam Juraszek. +* ENHANCEMENT: Thanks to Mark Haynes, the `staticConstructor` will now also be generated if a (private) constructor already exists. [Issue #2100](https://github.com/rzwitserloot/lombok/issues/2100) +* ENHANCEMENT: `val` is now capable of decoding the type of convoluted expressions (particularly if the right hand side involves lambdas and conditional (ternary) expressions). [Pull Request #2109](https://github.com/rzwitserloot/lombok/pull/2109) and [Pull Request #2138](https://github.com/rzwitserloot/lombok/pull/2138) with thanks to Alexander Bulgakov. +* ENHANCEMENT: You can now configure the generated builder class name via the config system, using key `lombok.builder.className`. See the [Builder documentation](https://projectlombok.org/features/Builder) and [SuperBuilder documentation](https://projectlombok.org/features/experimental/SuperBuilder) +* ENHANCEMENT: If you mix up eclipse's non-null support, such as `@NonNullByDefault`, with lombok's `@NonNull`, you get a bunch of warnings about dead code that are inappropriate. These warnings are now suppressed, thanks to a contribution from Till Brychcy! [Pull Request #2155](https://github.com/rzwitserloot/lombok/pull/2155) +* BUGFIX: Delombok would turn something like `List<byte[]>...` in a method parameter to `List<byte...>...` [Issue #2140](https://github.com/rzwitserloot/lombok/issues/2140) +* BUGFIX: Javac would generate the wrong equals and hashCode if a type-use annotation was put on an array type field [Issue #2165](https://github.com/rzwitserloot/lombok/issues/2165) * IMPROBABLE BREAKING CHANGE: Stricter validation of configuration keys dealing with identifiers and types (`lombok.log.fieldName`, `lombok.fieldNameConstants.innerTypeName`, `lombok.copyableAnnotations`). +>>>>>>> customlog ### v1.18.8 (May 7th, 2019) * FEATURE: You can now configure `@FieldNameConstants` to `CONSTANT_CASE` the generated constants, using a `lombok.config` option. See the [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants). [Issue #2092](https://github.com/rzwitserloot/lombok/issues/2092). * FEATURE: You can now suppress generation of the `builder` method when using `@Builder`; usually because you're only interested in the `toBuilder` method. As a convenience we won't emit warnings about missing `@Builder.Default` annotations when you do this. [Issue #2046](https://github.com/rzwitserloot/lombok/issues/2046) * FEATURE: You can now change the access modifier of generated builder classes. [Issue #2083](https://github.com/rzwitserloot/lombok/issues/2083). * FEATURE: When using `@NonNull`, or any other annotation that would result in a null-check, you can configure to generate an assert statement instead. [Issue #2078](https://github.com/rzwitserloot/lombok/issues/2078). -* FEATURE: Lombok now knows exactly how to treat `@com.fasterxml.jackson.annotation.JsonProperty` and will copy it to the right places for example when making builders. [Issue #1961](https://github.com/rzwitserloot/lombok/issues/1961) [Issue #1981](https://github.com/rzwitserloot/lombok/issues/1981). +* FEATURE: Lombok now knows exactly how to treat `@com.fasterxml.jackson.annotation.JsonProperty` and will copy it to the right places for example when making builders. [Issue #1961](https://github.com/rzwitserloot/lombok/issues/1961) [Issue #1981](https://github.com/rzwitserloot/lombok/issues/1981) * PLATFORM: A few lombok features (most notably delombok) failed on JDK12. [Issue #2082](https://github.com/rzwitserloot/lombok/issues/2082) * BUGFIX: var/val on methods that return an intersection type would now work in Eclipse. [Issue #1986](https://github.com/rzwitserloot/lombok/issues/1986) * BUGFIX: Fix for java6 regression if a field has javadoc. [Issue #2066](https://github.com/rzwitserloot/lombok/issues/2066) @@ -19,7 +26,7 @@ Lombok Changelog * BUGFIX: `@SuperBuilder` together with `@Singular` on non-lists would produce an erroneous `emptyList` call. [Issue #2104](https://github.com/rzwitserloot/lombok/issues/2104). * IMPROBABLE BREAKING CHANGE: For fields and parameters marked non-null, if the method body starts with an assert statement to ensure the value isn't null, no code to throw an exception will be generated. * IMPROBABLE BREAKING CHANGE: When using `ecj` to compile java code with `@Builder` or `@SuperBuilder` in it, and a builder setter method was generated for a `@NonNull`-marked method, no explicit null check would be present. However, running `javac` on the exact same file _would_ produce the null check. Now ecj also produces this null check. [Issue #2120](https://github.com/rzwitserloot/lombok/issues/2120). -* IMPROBABLE BREAKING CHANGE: We slightly changed the message of the exception lombok generates to handle `@NonNull` marked parameters. [Issue #2122](https://github.com/rzwitserloot/lombok/issues/2122). +* IMPROBABLE BREAKING CHANGE: We slightly changed the message of the exception lombok generates to handle `@NonNull` marked parameters. [Issue #2122](https://github.com/rzwitserloot/lombok/issues/2122) ### v1.18.6 (February 12th, 2019) * FEATURE: Javadoc on fields will now also be copied to the Builders' setters. Thanks for the contribution, Emil Lundberg. [Issue #2008](https://github.com/rzwitserloot/lombok/issues/2008) diff --git a/docker/gradle/files/build.gradle b/docker/gradle/files/build.gradle index 49923f04..bbf276c7 100644 --- a/docker/gradle/files/build.gradle +++ b/docker/gradle/files/build.gradle @@ -2,4 +2,5 @@ apply plugin: 'java' dependencies {
compileOnly files('lombok.jar')
+ annotationProcessor files('lombok.jar')
}
\ No newline at end of file diff --git a/src/core/lombok/Builder.java b/src/core/lombok/Builder.java index a60af9ee..dfa5ecb5 100644 --- a/src/core/lombok/Builder.java +++ b/src/core/lombok/Builder.java @@ -129,9 +129,9 @@ public @interface Builder { /** * Name of the builder class. * - * Default for {@code @Builder} on types and constructors: {@code (TypeName)Builder}. + * Default for {@code @Builder} on types and constructors: see the configkey {@code lombok.builder.className}, which if not set defaults to {@code (TypeName)Builder}. * <p> - * Default for {@code @Builder} on methods: {@code (ReturnTypeName)Builder}. + * Default for {@code @Builder} on methods: see the configkey {@code lombok.builder.className}, which if not set defaults to {@code (ReturnTypeName)Builder}. * * @return Name of the builder class that will be generated (or if it already exists, will be filled with builder elements). */ diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index ecfddb2a..dda0b54b 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -258,6 +258,13 @@ public class ConfigurationKeys { // ----- Builder ----- /** + * lombok configuration: {@code lombok.builder.classNames} = <String: aJavaIdentifier (optionally with a star as placeholder for the type name)> (Default: {@code *Builder}). + * + * For any usage of the {@code @Builder} annotation without an explicit {@code builderClassName} parameter, this value is used to determine the name of the builder class to generate (or to adapt if such an inner class already exists). + */ + public static final ConfigurationKey<String> BUILDER_CLASS_NAME = new ConfigurationKey<String>("lombok.builder.className", "Default name of the generated builder class. A * is replaced with the name of the relevant type (default = *Builder).") {}; + + /** * lombok configuration: {@code lombok.builder.flagUsage} = {@code WARNING} | {@code ERROR}. * * If set, <em>any</em> usage of {@code @Builder} results in a warning / error. diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index f04c541f..1a0633bf 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -114,6 +114,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; @@ -844,7 +845,6 @@ public class EclipseHandlerUtil { } public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { - if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING) { Object[] arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES, binding); binding = (TypeBinding) arr[0]; @@ -933,7 +933,12 @@ public class EclipseHandlerUtil { WildcardBinding wildcard = (WildcardBinding) binding; if (wildcard.boundKind == Wildcard.EXTENDS) { if (!allowCompound) { - return makeType(wildcard.bound, pos, false); + TypeBinding bound = wildcard.bound; + boolean isObject = bound.id == TypeIds.T_JavaLangObject; + TypeBinding[] otherBounds = wildcard.otherBounds; + if (isObject && otherBounds != null && otherBounds.length > 0) { + return makeType(otherBounds[0], pos, false); + } else return makeType(bound, pos, false); } else { Wildcard out = new Wildcard(Wildcard.EXTENDS); setGeneratedBy(out, pos); @@ -960,7 +965,8 @@ public class EclipseHandlerUtil { // Finally, add however many nullTypeArgument[] arrays as that are missing, inverse the list, toArray it, and use that as PTR's typeArgument argument. List<TypeReference[]> params = new ArrayList<TypeReference[]>(); - /* Calculate generics */ { + /* Calculate generics */ + if (!(binding instanceof RawTypeBinding)) { TypeBinding b = binding; while (true) { boolean isFinalStop = b.isLocalType() || !b.isMemberType() || b.enclosingType() == null; diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 96431a83..aa9d2147 100755 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -209,6 +209,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { List<EclipseNode> nonFinalNonDefaultedFields = null; + if (builderClassName.isEmpty()) builderClassName = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME); + if (builderClassName == null || builderClassName.isEmpty()) builderClassName = "*Builder"; + boolean replaceNameInBuilderClassName = builderClassName.contains("*"); + if (parent.get() instanceof TypeDeclaration) { tdParent = parent; TypeDeclaration td = (TypeDeclaration) tdParent.get(); @@ -265,7 +269,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { typeParams = td.typeParameters; thrownExceptions = null; nameOfStaticBuilderMethod = null; - if (builderClassName.isEmpty()) builderClassName = new String(td.name) + "Builder"; + if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", new String(td.name)); + replaceNameInBuilderClassName = false; } else if (parent.get() instanceof ConstructorDeclaration) { ConstructorDeclaration cd = (ConstructorDeclaration) parent.get(); if (cd.typeParameters != null && cd.typeParameters.length > 0) { @@ -279,12 +284,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { typeParams = td.typeParameters; thrownExceptions = cd.thrownExceptions; nameOfStaticBuilderMethod = null; - if (builderClassName.isEmpty()) builderClassName = new String(cd.selector) + "Builder"; + if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", new String(cd.selector)); + replaceNameInBuilderClassName = false; } else if (parent.get() instanceof MethodDeclaration) { MethodDeclaration md = (MethodDeclaration) parent.get(); tdParent = parent.up(); isStatic = md.isStatic(); - + if (toBuilder) { final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type."; char[] token; @@ -360,7 +366,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { typeParams = md.typeParameters; thrownExceptions = md.thrownExceptions; nameOfStaticBuilderMethod = md.selector; - if (builderClassName.isEmpty()) { + if (replaceNameInBuilderClassName) { char[] token; if (md.returnType instanceof QualifiedTypeReference) { char[][] tokens = ((QualifiedTypeReference) md.returnType).tokens; @@ -387,7 +393,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { token = newToken; } - builderClassName = new String(token) + "Builder"; + builderClassName = builderClassName.replace("*", new String(token)); } } else { annotationNode.addError("@Builder is only supported on types, constructors, and methods."); diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 9a86d372..f204bc24 100755 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -203,7 +203,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { } // Set the names of the builder classes. - String builderClassName = String.valueOf(td.name) + "Builder"; + String builderClassNameTemplate = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME); + if (builderClassNameTemplate == null || builderClassNameTemplate.isEmpty()) builderClassNameTemplate = "*Builder"; + String builderClassName = builderClassNameTemplate.replace("*", String.valueOf(td.name)); String builderImplClassName = builderClassName + "Impl"; typeParams = td.typeParameters != null ? td.typeParameters : new TypeParameter[0]; @@ -228,7 +230,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { if (extendsClause instanceof QualifiedTypeReference) { QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference)extendsClause; String superclassClassName = String.valueOf(qualifiedTypeReference.getLastToken()); - String superclassBuilderClassName = superclassClassName + "Builder"; + String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName); char[][] tokens = Arrays.copyOf(qualifiedTypeReference.tokens, qualifiedTypeReference.tokens.length + 1); tokens[tokens.length] = superclassBuilderClassName.toCharArray(); diff --git a/src/core/lombok/javac/JavacResolution.java b/src/core/lombok/javac/JavacResolution.java index abbf6726..7f940d2a 100644 --- a/src/core/lombok/javac/JavacResolution.java +++ b/src/core/lombok/javac/JavacResolution.java @@ -336,7 +336,7 @@ public class JavacResolution { if (type instanceof ClassType) { List<Type> ifaces = ((ClassType) type).interfaces_field; Type supertype = ((ClassType) type).supertype_field; - if (ifaces != null && ifaces.length() == 1) { + if (isObject(supertype) && ifaces != null && ifaces.length() > 0) { return typeToJCTree(ifaces.get(0), ast, allowCompound, allowVoid); } if (supertype != null) return typeToJCTree(supertype, ast, allowCompound, allowVoid); @@ -402,6 +402,10 @@ public class JavacResolution { return genericsToJCTreeNodes(generics, ast, replacement); } + private static boolean isObject(Type supertype) { + return supertype.tsym.toString().equals("java.lang.Object"); + } + private static JCExpression genericsToJCTreeNodes(List<Type> generics, JavacAST ast, JCExpression rawTypeNode) throws TypeNotConvertibleException { if (generics != null && !generics.isEmpty()) { ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index d758f602..b339c2ca 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -157,6 +157,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { ArrayList<JavacNode> nonFinalNonDefaultedFields = null; + if (builderClassName.isEmpty()) builderClassName = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME); + if (builderClassName == null || builderClassName.isEmpty()) builderClassName = "*Builder"; + boolean replaceNameInBuilderClassName = builderClassName.contains("*"); + if (parent.get() instanceof JCClassDecl) { tdParent = parent; JCClassDecl td = (JCClassDecl) tdParent.get(); @@ -211,7 +215,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { typeParams = td.typarams; thrownExceptions = List.nil(); nameOfBuilderMethod = null; - if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder"; + if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString()); + replaceNameInBuilderClassName = false; } else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) { JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get(); if (!jmd.typarams.isEmpty()) { @@ -225,7 +230,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { typeParams = td.typarams; thrownExceptions = jmd.thrown; nameOfBuilderMethod = null; - if (builderClassName.isEmpty()) builderClassName = td.name.toString() + "Builder"; + if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString()); + replaceNameInBuilderClassName = false; } else if (fillParametersFrom != null) { tdParent = parent.up(); JCClassDecl td = (JCClassDecl) tdParent.get(); @@ -239,9 +245,10 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { if (returnType instanceof JCTypeApply) { returnType = cloneType(tdParent.getTreeMaker(), returnType, ast, annotationNode.getContext()); } - if (builderClassName.isEmpty()) { + if (replaceNameInBuilderClassName) { + String replStr = null; if (returnType instanceof JCFieldAccess) { - builderClassName = ((JCFieldAccess) returnType).name.toString() + "Builder"; + replStr = ((JCFieldAccess) returnType).name.toString(); } else if (returnType instanceof JCIdent) { Name n = ((JCIdent) returnType).name; @@ -251,27 +258,30 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { return; } } - builderClassName = n.toString() + "Builder"; + replStr = n.toString(); } else if (returnType instanceof JCPrimitiveTypeTree) { - builderClassName = returnType.toString() + "Builder"; - if (Character.isLowerCase(builderClassName.charAt(0))) { - builderClassName = Character.toTitleCase(builderClassName.charAt(0)) + builderClassName.substring(1); + replStr = returnType.toString(); + if (Character.isLowerCase(replStr.charAt(0))) { + replStr = Character.toTitleCase(replStr.charAt(0)) + replStr.substring(1); } } else if (returnType instanceof JCTypeApply) { JCExpression clazz = ((JCTypeApply) returnType).clazz; if (clazz instanceof JCFieldAccess) { - builderClassName = ((JCFieldAccess) clazz).name + "Builder"; + replStr = ((JCFieldAccess) clazz).name.toString(); } else if (clazz instanceof JCIdent) { - builderClassName = ((JCIdent) clazz).name + "Builder"; + replStr = ((JCIdent) clazz).name.toString(); } } - if (builderClassName.isEmpty()) { + if (replStr == null || replStr.isEmpty()) { // This shouldn't happen. System.err.println("Lombok bug ID#20140614-1651: javac HandleBuilder: return type to name conversion failed: " + returnType.getClass()); - builderClassName = td.name.toString() + "Builder"; + replStr = td.name.toString(); } + builderClassName = builderClassName.replace("*", replStr); + replaceNameInBuilderClassName = false; } + if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString()); if (toBuilder) { final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type."; if (returnType instanceof JCArrayTypeTree) { diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index cb12bd4e..e4d7fa7f 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -25,6 +25,7 @@ import static lombok.core.handlers.HandlerUtil.handleFlagUsage; import static lombok.javac.Javac.*; import static lombok.javac.handlers.JavacHandlerUtil.*; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -234,7 +235,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas for (Included<JavacNode, EqualsAndHashCode.Include> member : members) { JavacNode memberNode = member.getNode(); - JCExpression fType = getFieldType(memberNode, fieldAccess); + JCExpression fType = unnotate(getFieldType(memberNode, fieldAccess)); boolean isMethod = memberNode.getKind() == Kind.METHOD; JCExpression fieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess); @@ -279,9 +280,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas break; } } else if (fType instanceof JCArrayTypeTree) { + JCArrayTypeTree array = (JCArrayTypeTree) fType; /* java.util.Arrays.deepHashCode(this.fieldName) //use just hashCode() for primitive arrays. */ - boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree; - boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree; + boolean multiDim = unnotate(array.elemtype) instanceof JCArrayTypeTree; + boolean primitiveArray = unnotate(array.elemtype) instanceof JCPrimitiveTypeTree; boolean useDeepHC = multiDim || !primitiveArray; JCExpression hcMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode"); @@ -430,7 +432,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas JavacNode memberNode = member.getNode(); boolean isMethod = memberNode.getKind() == Kind.METHOD; - JCExpression fType = getFieldType(memberNode, fieldAccess); + JCExpression fType = unnotate(getFieldType(memberNode, fieldAccess)); JCExpression thisFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess); JCExpression otherFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode, maker.Ident(otherName)) : createFieldAccessor(maker, memberNode, fieldAccess, maker.Ident(otherName)); if (fType instanceof JCPrimitiveTypeTree) { @@ -450,9 +452,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas break; } } else if (fType instanceof JCArrayTypeTree) { + JCArrayTypeTree array = (JCArrayTypeTree) fType; /* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */ - boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree; - boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree; + boolean multiDim = unnotate(array.elemtype) instanceof JCArrayTypeTree; + boolean primitiveArray = unnotate(array.elemtype) instanceof JCPrimitiveTypeTree; boolean useDeepEquals = multiDim || !primitiveArray; JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals"); @@ -522,4 +525,30 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas public JCStatement returnBool(JavacTreeMaker maker, boolean bool) { return maker.Return(maker.Literal(CTC_BOOLEAN, bool ? 1 : 0)); } + + private boolean jcAnnotatedTypeInit; + private Class<?> jcAnnotatedTypeClass = null; + private Field jcAnnotatedTypeUnderlyingTypeField = null; + + private JCExpression unnotate(JCExpression type) { + if (!isJcAnnotatedType(type)) return type; + if (jcAnnotatedTypeUnderlyingTypeField == null) return type; + try { + return (JCExpression) jcAnnotatedTypeUnderlyingTypeField.get(type); + } catch (Exception ignore) {} + return type; + } + + private boolean isJcAnnotatedType(JCExpression o) { + if (o == null) return false; + if (!jcAnnotatedTypeInit) { + try { + jcAnnotatedTypeClass = Class.forName("com.sun.tools.javac.tree.JCTree$JCAnnotatedType", false, o.getClass().getClassLoader()); + jcAnnotatedTypeUnderlyingTypeField = jcAnnotatedTypeClass.getDeclaredField("underlyingType"); + } + catch (Exception ignore) {} + jcAnnotatedTypeInit = true; + } + return jcAnnotatedTypeClass == o.getClass(); + } } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 0fcaa5f8..9120fa07 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -177,7 +177,9 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { } // Set the names of the builder classes. - String builderClassName = td.name.toString() + "Builder"; + String builderClassNameTemplate = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME); + if (builderClassNameTemplate == null || builderClassNameTemplate.isEmpty()) builderClassNameTemplate = "*Builder"; + String builderClassName = builderClassNameTemplate.replace("*", td.name.toString()); String builderImplClassName = builderClassName + "Impl"; JCTree extendsClause = Javac.getExtendsClause(td); JCExpression superclassBuilderClassExpression = null; @@ -189,11 +191,11 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { } if (extendsClause instanceof JCFieldAccess) { Name superclassClassName = ((JCFieldAccess)extendsClause).getIdentifier(); - String superclassBuilderClassName = superclassClassName + "Builder"; + String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName); superclassBuilderClassExpression = tdParent.getTreeMaker().Select((JCFieldAccess) extendsClause, - tdParent.toName(superclassBuilderClassName)); + tdParent.toName(superclassBuilderClassName)); } else if (extendsClause != null) { - String superclassBuilderClassName = extendsClause.toString() + "Builder"; + String superclassBuilderClassName = builderClassNameTemplate.replace("*", extendsClause.toString()); superclassBuilderClassExpression = chainDots(tdParent, extendsClause.toString(), superclassBuilderClassName); } // If there is no superclass, superclassBuilderClassExpression is still == null at this point. diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 3477c51c..1532319f 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -692,7 +692,10 @@ public class PrettyPrinter extends JCTree.Visitor { @Override public void visitTypeApply(JCTypeApply tree) { print(tree.clazz); print("<"); + boolean temp = innermostArrayBracketsAreVarargs; + innermostArrayBracketsAreVarargs = false; print(tree.arguments, ", "); + innermostArrayBracketsAreVarargs = temp; print(">"); } diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index 0e74dfaf..24c1216e 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -122,6 +122,7 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { patchEcjTransformers(sm, ecjOnly); patchExtensionMethod(sm, ecjOnly); patchRenameField(sm); + patchNullCheck(sm); if (reloadExistingClasses) sm.reloadClasses(instrumentation); } @@ -774,4 +775,24 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable { .build()); } } + + private static void patchNullCheck(ScriptManager sm) { + /* Avoid warnings caused by the null check generated for lombok.NonNull if NonNullByDefault is used. */ + + /* Avoid "Redundant null check: comparing '@NonNull String' against null" */ + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.problem.ProblemReporter", "expressionNonNullComparison", "boolean", "org.eclipse.jdt.internal.compiler.ast.Expression", "boolean")) + .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .valueMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "returnTrue", "boolean", "java.lang.Object")) + .request(StackRequest.PARAM1) + .transplant().build()); + + /* Avoid "Dead code" */ + sm.addScript(ScriptBuilder.exitEarly() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.problem.ProblemReporter", "fakeReachable", "void", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .decisionMethod(new Hook("lombok.launch.PatchFixesHider$PatchFixes", "isGenerated", "boolean", "org.eclipse.jdt.internal.compiler.ast.ASTNode")) + .request(StackRequest.PARAM1) + .transplant().build()); + } + } diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java index b32c99cd..0c66bb31 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java +++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java @@ -21,16 +21,27 @@ */ package lombok.eclipse.agent; +import lombok.permit.Permit; +import org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.ForeachStatement; +import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression; import org.eclipse.jdt.internal.compiler.ast.ImportReference; +import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -42,13 +53,15 @@ import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; - -import lombok.permit.Permit; +import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; +import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import java.lang.reflect.Field; +import static lombok.Lombok.sneakyThrow; import static lombok.eclipse.Eclipse.poss; import static lombok.eclipse.handlers.EclipseHandlerUtil.makeType; +import static org.eclipse.jdt.core.compiler.CategorizedProblem.CAT_TYPE; public class PatchVal { @@ -263,15 +276,11 @@ public class PatchVal { resolved = null; } if (resolved != null) { - if (resolved.getClass().getSimpleName().startsWith("IntersectionTypeBinding")) { - // We intentionally deconstruct these into simply 'Object', because picking an arbitrary type amongst the intersection feels worse. - } else { - try { - replacement = makeType(resolved, local.type, false); - if (!decomponent) init.resolvedType = replacement.resolveType(scope); - } catch (Exception e) { - // Some type thing failed. - } + try { + replacement = makeType(resolved, local.type, false); + if (!decomponent) init.resolvedType = replacement.resolveType(scope); + } catch (Exception e) { + // Some type thing failed. } } } @@ -357,11 +366,106 @@ public class PatchVal { } private static TypeBinding resolveForExpression(Expression collection, BlockScope scope) { + CompilationUnitDeclaration referenceContext = scope.compilationUnitScope().referenceContext; + ProblemReporter oldProblemReporter = referenceContext.problemReporter; + referenceContext.problemReporter = new ProblemReporter(DefaultErrorHandlingPolicies.exitOnFirstError(), + oldProblemReporter.options, oldProblemReporter.problemFactory); try { return collection.resolveType(scope); } catch (ArrayIndexOutOfBoundsException e) { // Known cause of issues; for example: val e = mth("X"), where mth takes 2 arguments. return null; + } catch (AbortCompilation e) { + if (collection instanceof ConditionalExpression) { + ConditionalExpression cexp = (ConditionalExpression) collection; + Expression ifTrue = cexp.valueIfTrue; + Expression ifFalse = cexp.valueIfFalse; + TypeBinding ifTrueResolvedType = ifTrue.resolvedType; + CategorizedProblem problem = e.problem; + if (ifTrueResolvedType != null && ifFalse.resolvedType == null && problem.getCategoryID() == CAT_TYPE) { + CompilationResult compilationResult = e.compilationResult; + CategorizedProblem[] problems = compilationResult.problems; + int problemCount = compilationResult.problemCount; + for (int i = 0; i < problemCount; ++i) { + if (problems[i] == problem) { + problems[i] = null; + if (i + 1 < problemCount) { + System.arraycopy(problems, i + 1, problems, i, problemCount - i + 1); + } + break; + } + } + compilationResult.removeProblem(problem); + if (!compilationResult.hasErrors()) { + clearIgnoreFurtherInvestigationField(scope.referenceContext()); + setValue(getField(CompilationResult.class, "hasMandatoryErrors"), compilationResult, false); + } + + if (ifFalse instanceof FunctionalExpression) { + FunctionalExpression functionalExpression = (FunctionalExpression) ifFalse; + functionalExpression.setExpectedType(ifTrueResolvedType); + } + if (ifFalse.resolvedType == null) { + ifFalse.resolve(scope); + } + + return ifTrueResolvedType; + } + } + throw e; + } finally { + referenceContext.problemReporter = oldProblemReporter; + } + } + + private static void clearIgnoreFurtherInvestigationField(ReferenceContext currentContext) { + if (currentContext instanceof AbstractMethodDeclaration) { + AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) currentContext; + methodDeclaration.ignoreFurtherInvestigation = false; + } else if (currentContext instanceof LambdaExpression) { + LambdaExpression lambdaExpression = (LambdaExpression) currentContext; + setValue(getField(LambdaExpression.class, "ignoreFurtherInvestigation"), lambdaExpression, false); + + Scope parent = lambdaExpression.enclosingScope.parent; + while (parent != null) { + switch(parent.kind) { + case Scope.CLASS_SCOPE: + case Scope.METHOD_SCOPE: + ReferenceContext parentAST = parent.referenceContext(); + if (parentAST != lambdaExpression) { + clearIgnoreFurtherInvestigationField(parentAST); + return; + } + default: + parent = parent.parent; + break; + } + } + + } else if (currentContext instanceof TypeDeclaration) { + TypeDeclaration typeDeclaration = (TypeDeclaration) currentContext; + typeDeclaration.ignoreFurtherInvestigation = false; + } else if (currentContext instanceof CompilationUnitDeclaration) { + CompilationUnitDeclaration typeDeclaration = (CompilationUnitDeclaration) currentContext; + typeDeclaration.ignoreFurtherInvestigation = false; + } else { + throw new UnsupportedOperationException("clearIgnoreFurtherInvestigationField for " + currentContext.getClass()); + } + } + + private static void setValue(Field field, Object object, Object value) { + try { + field.set(object, value); + } catch (IllegalAccessException e) { + throw sneakyThrow(e); + } + } + + private static Field getField(Class clazz, String name) { + try { + return Permit.getField(clazz, name); + } catch (NoSuchFieldException e) { + throw sneakyThrow(e); } } } diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index 3741aba8..563beab1 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -315,7 +315,17 @@ final class PatchFixesHider { } return result; } - + + public static boolean isGenerated(org.eclipse.jdt.internal.compiler.ast.ASTNode node) { + boolean result = false; + try { + result = node.getClass().getField("$generatedBy").get(node) != null; + } catch (Exception e) { + // better to assume it isn't generated + } + return result; + } + public static boolean isListRewriteOnGeneratedNode(org.eclipse.jdt.core.dom.rewrite.ListRewrite rewrite) { return isGenerated(rewrite.getParent()); } diff --git a/test/pretty/resource/after/ArrayAndVarargs.java b/test/pretty/resource/after/ArrayAndVarargs.java new file mode 100644 index 00000000..9727bff6 --- /dev/null +++ b/test/pretty/resource/after/ArrayAndVarargs.java @@ -0,0 +1,7 @@ +import java.util.List; +class ArrayAndVarargs { + void test(List<String[]>... foo) { + } + void test2(byte[]... foo) { + } +} diff --git a/test/pretty/resource/before/ArrayAndVarargs.java b/test/pretty/resource/before/ArrayAndVarargs.java new file mode 100644 index 00000000..38c9b276 --- /dev/null +++ b/test/pretty/resource/before/ArrayAndVarargs.java @@ -0,0 +1,9 @@ +import java.util.List; + +class ArrayAndVarargs { + void test(List<String[]>... foo) { + } + + void test2(byte[]... foo) { + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/BuilderComplex.java b/test/transform/resource/after-delombok/BuilderComplex.java index a89d7114..c63d7b59 100644 --- a/test/transform/resource/after-delombok/BuilderComplex.java +++ b/test/transform/resource/after-delombok/BuilderComplex.java @@ -3,7 +3,7 @@ class BuilderComplex { private static <T extends Number> void testVoidWithGenerics(T number, int arg2, String arg3, BuilderComplex selfRef) { } @java.lang.SuppressWarnings("all") - public static class VoidBuilder<T extends Number> { + public static class TestVoidName<T extends Number> { @java.lang.SuppressWarnings("all") private T number; @java.lang.SuppressWarnings("all") @@ -13,25 +13,25 @@ class BuilderComplex { @java.lang.SuppressWarnings("all") private BuilderComplex selfRef; @java.lang.SuppressWarnings("all") - VoidBuilder() { + TestVoidName() { } @java.lang.SuppressWarnings("all") - public VoidBuilder<T> number(final T number) { + public TestVoidName<T> number(final T number) { this.number = number; return this; } @java.lang.SuppressWarnings("all") - public VoidBuilder<T> arg2(final int arg2) { + public TestVoidName<T> arg2(final int arg2) { this.arg2 = arg2; return this; } @java.lang.SuppressWarnings("all") - public VoidBuilder<T> arg3(final String arg3) { + public TestVoidName<T> arg3(final String arg3) { this.arg3 = arg3; return this; } @java.lang.SuppressWarnings("all") - public VoidBuilder<T> selfRef(final BuilderComplex selfRef) { + public TestVoidName<T> selfRef(final BuilderComplex selfRef) { this.selfRef = selfRef; return this; } @@ -42,11 +42,11 @@ class BuilderComplex { @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "BuilderComplex.VoidBuilder(number=" + this.number + ", arg2=" + this.arg2 + ", arg3=" + this.arg3 + ", selfRef=" + this.selfRef + ")"; + return "BuilderComplex.TestVoidName(number=" + this.number + ", arg2=" + this.arg2 + ", arg3=" + this.arg3 + ", selfRef=" + this.selfRef + ")"; } } @java.lang.SuppressWarnings("all") - public static <T extends Number> VoidBuilder<T> builder() { - return new VoidBuilder<T>(); + public static <T extends Number> TestVoidName<T> builder() { + return new TestVoidName<T>(); } } diff --git a/test/transform/resource/after-delombok/BuilderCustomName.java b/test/transform/resource/after-delombok/BuilderCustomName.java new file mode 100644 index 00000000..4db08220 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderCustomName.java @@ -0,0 +1,47 @@ +import java.util.List; +class BuilderCustomName<T> { + private final int field; + @java.lang.SuppressWarnings("all") + public static abstract class SimpleTestBuilder<T, C extends BuilderCustomName<T>, B extends SimpleTestBuilder<T, C, B>> { + @java.lang.SuppressWarnings("all") + private int field; + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.SuppressWarnings("all") + public B field(final int field) { + this.field = field; + return self(); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderCustomName.SimpleTestBuilder(field=" + this.field + ")"; + } + } + @java.lang.SuppressWarnings("all") + private static final class SimpleTestBuilderImpl<T> extends SimpleTestBuilder<T, BuilderCustomName<T>, SimpleTestBuilderImpl<T>> { + @java.lang.SuppressWarnings("all") + private SimpleTestBuilderImpl() { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected SimpleTestBuilderImpl<T> self() { + return this; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public BuilderCustomName<T> build() { + return new BuilderCustomName<T>(this); + } + } + @java.lang.SuppressWarnings("all") + protected BuilderCustomName(final SimpleTestBuilder<T, ?, ?> b) { + this.field = b.field; + } + @java.lang.SuppressWarnings("all") + public static <T> SimpleTestBuilder<T, ?, ?> builder() { + return new SimpleTestBuilderImpl<T>(); + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeAnnotated.java b/test/transform/resource/after-delombok/EqualsAndHashCodeAnnotated.java new file mode 100644 index 00000000..64b6f4d3 --- /dev/null +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeAnnotated.java @@ -0,0 +1,51 @@ +import java.lang.annotation.*; + +class EqualsAndHashCodeAnnotated { + @Annotated + int primitive; + @Annotated + Object object; + int @Annotated [] primitiveValues; + int @Annotated [] @Annotated [] morePrimitiveValues; + Integer @Annotated [] objectValues; + Integer @Annotated [] @Annotated [] moreObjectValues; + @Target(ElementType.TYPE_USE) + @Retention(RetentionPolicy.SOURCE) + @interface Annotated { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public boolean equals(final java.lang.Object o) { + if (o == this) return true; + if (!(o instanceof EqualsAndHashCodeAnnotated)) return false; + final EqualsAndHashCodeAnnotated other = (EqualsAndHashCodeAnnotated) o; + if (!other.canEqual((java.lang.Object) this)) return false; + if (this.primitive != other.primitive) return false; + final java.lang.Object this$object = this.object; + final java.lang.Object other$object = other.object; + if (this$object == null ? other$object != null : !this$object.equals(other$object)) return false; + if (!java.util.Arrays.equals(this.primitiveValues, other.primitiveValues)) return false; + if (!java.util.Arrays.deepEquals(this.morePrimitiveValues, other.morePrimitiveValues)) return false; + if (!java.util.Arrays.deepEquals(this.objectValues, other.objectValues)) return false; + if (!java.util.Arrays.deepEquals(this.moreObjectValues, other.moreObjectValues)) return false; + return true; + } + @java.lang.SuppressWarnings("all") + protected boolean canEqual(final java.lang.Object other) { + return other instanceof EqualsAndHashCodeAnnotated; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.primitive; + final java.lang.Object $object = this.object; + result = result * PRIME + ($object == null ? 43 : $object.hashCode()); + result = result * PRIME + java.util.Arrays.hashCode(this.primitiveValues); + result = result * PRIME + java.util.Arrays.deepHashCode(this.morePrimitiveValues); + result = result * PRIME + java.util.Arrays.deepHashCode(this.objectValues); + result = result * PRIME + java.util.Arrays.deepHashCode(this.moreObjectValues); + return result; + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValInLambda.java b/test/transform/resource/after-delombok/ValInLambda.java index 7ce1e1b4..861fb9da 100644 --- a/test/transform/resource/after-delombok/ValInLambda.java +++ b/test/transform/resource/after-delombok/ValInLambda.java @@ -2,17 +2,26 @@ class ValInLambda { Runnable foo = (Runnable) () -> { final int i = 1; + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; }; - + public void easyLambda() { Runnable foo = (Runnable) () -> { final int i = 1; }; } - + public void easyIntersectionLambda() { Runnable foo = (Runnable) () -> { final int i = 1; }; } + + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + final java.lang.Runnable fooInner = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + }; + } } diff --git a/test/transform/resource/after-delombok/ValLambda.java b/test/transform/resource/after-delombok/ValLambda.java index 9214b490..24ae3b5f 100644 --- a/test/transform/resource/after-delombok/ValLambda.java +++ b/test/transform/resource/after-delombok/ValLambda.java @@ -1,21 +1,33 @@ // version 8: class ValLambda { + static { + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + } + + { + final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { + } : System.out::println; + } + public void easyLambda() { final java.lang.Runnable foo = (Runnable) () -> { }; } + public void easyIntersectionLambda() { - final java.lang.Object foo = (Runnable & java.io.Serializable) () -> { + final java.lang.Runnable foo = (Runnable & java.io.Serializable) () -> { }; - final java.lang.Object bar = (java.io.Serializable & Runnable) () -> { + final java.io.Serializable bar = (java.io.Serializable & Runnable) () -> { }; } + public void easyLubLambda() { final java.lang.Runnable foo = (System.currentTimeMillis() > 0) ? (Runnable) () -> { - } : (Runnable) System.out::println; + } : System.out::println; + final java.lang.Runnable foo1 = (System.currentTimeMillis() > 0) ? (Runnable) System.out::println : System.out::println; + final java.util.function.Function foo2 = (System.currentTimeMillis() < 0) ? (java.util.function.Function) r -> "" : r -> System.currentTimeMillis(); + java.util.function.Function foo3 = (System.currentTimeMillis() < 0) ? (java.util.function.Function) r -> "" : r -> System.currentTimeMillis(); + final java.util.function.Function<java.lang.String, java.lang.String> foo4 = (System.currentTimeMillis() < 0) ? (java.util.function.Function<String, String>) r -> "" : r -> String.valueOf(System.currentTimeMillis()); } -// public void castLubLambda() { -// Runnable foo = (Runnable) ((System.currentTimeMillis() > 0) ? () -> {} : System.out::println); -// lombok.val foo = (Runnable) ((System.currentTimeMillis() > 0) ? () -> {} : System.out::println); -// } -} +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValWeirdTypes.java b/test/transform/resource/after-delombok/ValWeirdTypes.java index a6bc9bd4..8b399fe8 100644 --- a/test/transform/resource/after-delombok/ValWeirdTypes.java +++ b/test/transform/resource/after-delombok/ValWeirdTypes.java @@ -56,8 +56,14 @@ public class ValWeirdTypes<Z> { final int singleInt = copy[0]; } public void arraysAsList() { - final java.util.List<java.lang.Class<? extends java.lang.Object>> x = Arrays.asList(String.class, BigDecimal.class); - for (final java.lang.Class<?> y : x) { + final java.util.List<java.lang.Class<? extends java.io.Serializable>> x = Arrays.asList(String.class, BigDecimal.class); + for (final java.lang.Class<? extends java.io.Serializable> y : x) { + } + } + @SuppressWarnings("all") + public void arraysAsList2() { + final java.util.List<java.lang.Class<? extends java.lang.Comparable>> x = Arrays.asList(String.class, BigDecimal.class, Comparable.class); + for (final java.lang.Class<? extends java.lang.Comparable> y : x) { } } } diff --git a/test/transform/resource/after-ecj/BuilderComplex.java b/test/transform/resource/after-ecj/BuilderComplex.java index 93d70fe9..23dbf058 100644 --- a/test/transform/resource/after-ecj/BuilderComplex.java +++ b/test/transform/resource/after-ecj/BuilderComplex.java @@ -1,27 +1,27 @@ import java.util.List; import lombok.Builder; class BuilderComplex { - public static @java.lang.SuppressWarnings("all") class VoidBuilder<T extends Number> { + public static @java.lang.SuppressWarnings("all") class TestVoidName<T extends Number> { private @java.lang.SuppressWarnings("all") T number; private @java.lang.SuppressWarnings("all") int arg2; private @java.lang.SuppressWarnings("all") String arg3; private @java.lang.SuppressWarnings("all") BuilderComplex selfRef; - @java.lang.SuppressWarnings("all") VoidBuilder() { + @java.lang.SuppressWarnings("all") TestVoidName() { super(); } - public @java.lang.SuppressWarnings("all") VoidBuilder<T> number(final T number) { + public @java.lang.SuppressWarnings("all") TestVoidName<T> number(final T number) { this.number = number; return this; } - public @java.lang.SuppressWarnings("all") VoidBuilder<T> arg2(final int arg2) { + public @java.lang.SuppressWarnings("all") TestVoidName<T> arg2(final int arg2) { this.arg2 = arg2; return this; } - public @java.lang.SuppressWarnings("all") VoidBuilder<T> arg3(final String arg3) { + public @java.lang.SuppressWarnings("all") TestVoidName<T> arg3(final String arg3) { this.arg3 = arg3; return this; } - public @java.lang.SuppressWarnings("all") VoidBuilder<T> selfRef(final BuilderComplex selfRef) { + public @java.lang.SuppressWarnings("all") TestVoidName<T> selfRef(final BuilderComplex selfRef) { this.selfRef = selfRef; return this; } @@ -29,7 +29,7 @@ class BuilderComplex { BuilderComplex.<T>testVoidWithGenerics(number, arg2, arg3, selfRef); } public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { - return (((((((("BuilderComplex.VoidBuilder(number=" + this.number) + ", arg2=") + this.arg2) + ", arg3=") + this.arg3) + ", selfRef=") + this.selfRef) + ")"); + return (((((((("BuilderComplex.TestVoidName(number=" + this.number) + ", arg2=") + this.arg2) + ", arg3=") + this.arg3) + ", selfRef=") + this.selfRef) + ")"); } } BuilderComplex() { @@ -37,7 +37,7 @@ class BuilderComplex { } private static @Builder(buildMethodName = "execute") <T extends Number>void testVoidWithGenerics(T number, int arg2, String arg3, BuilderComplex selfRef) { } - public static @java.lang.SuppressWarnings("all") <T extends Number>VoidBuilder<T> builder() { - return new VoidBuilder<T>(); + public static @java.lang.SuppressWarnings("all") <T extends Number>TestVoidName<T> builder() { + return new TestVoidName<T>(); } } diff --git a/test/transform/resource/after-ecj/BuilderCustomName.java b/test/transform/resource/after-ecj/BuilderCustomName.java new file mode 100644 index 00000000..1067a9d1 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderCustomName.java @@ -0,0 +1,37 @@ +import java.util.List; +@lombok.experimental.SuperBuilder class BuilderCustomName<T> { + public static abstract @java.lang.SuppressWarnings("all") class SimpleTestBuilder<T, C extends BuilderCustomName<T>, B extends SimpleTestBuilder<T, C, B>> { + private @java.lang.SuppressWarnings("all") int field; + public SimpleTestBuilder() { + super(); + } + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); + public @java.lang.SuppressWarnings("all") B field(final int field) { + this.field = field; + return self(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderCustomName.SimpleTestBuilder(field=" + this.field) + ")"); + } + } + private static final @java.lang.SuppressWarnings("all") class SimpleTestBuilderImpl<T> extends SimpleTestBuilder<T, BuilderCustomName<T>, SimpleTestBuilderImpl<T>> { + private SimpleTestBuilderImpl() { + super(); + } + protected @java.lang.Override @java.lang.SuppressWarnings("all") SimpleTestBuilderImpl<T> self() { + return this; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") BuilderCustomName<T> build() { + return new BuilderCustomName<T>(this); + } + } + private final int field; + protected @java.lang.SuppressWarnings("all") BuilderCustomName(final SimpleTestBuilder<T, ?, ?> b) { + super(); + this.field = b.field; + } + public static @java.lang.SuppressWarnings("all") <T>SimpleTestBuilder<T, ?, ?> builder() { + return new SimpleTestBuilderImpl<T>(); + } +} diff --git a/test/transform/resource/after-ecj/ValInLambda.java b/test/transform/resource/after-ecj/ValInLambda.java index 7669789b..0fac61e9 100644 --- a/test/transform/resource/after-ecj/ValInLambda.java +++ b/test/transform/resource/after-ecj/ValInLambda.java @@ -1,9 +1,9 @@ -// version 8: - import lombok.val; class ValInLambda { Runnable foo = (Runnable) () -> { final @val int i = 1; + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); }; ValInLambda() { super(); @@ -18,4 +18,10 @@ class ValInLambda { final @val int i = 1; }; } + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + final @lombok.val java.lang.Runnable fooInner = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); +}; + } } diff --git a/test/transform/resource/after-ecj/ValLambda.java b/test/transform/resource/after-ecj/ValLambda.java index 4bf3265b..5b52869f 100644 --- a/test/transform/resource/after-ecj/ValLambda.java +++ b/test/transform/resource/after-ecj/ValLambda.java @@ -1,4 +1,14 @@ class ValLambda { + static { + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); + } + { + final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { +} : System.out::println); + } + <clinit>() { + } ValLambda() { super(); } @@ -7,13 +17,17 @@ class ValLambda { }; } public void easyIntersectionLambda() { - final @lombok.val java.lang.Object foo = (Runnable & java.io.Serializable) () -> { + final @lombok.val java.lang.Runnable foo = (Runnable & java.io.Serializable) () -> { }; - final @lombok.val java.lang.Object bar = (java.io.Serializable & Runnable) () -> { + final @lombok.val java.io.Serializable bar = (java.io.Serializable & Runnable) () -> { }; } public void easyLubLambda() { final @lombok.val java.lang.Runnable foo = ((System.currentTimeMillis() > 0) ? (Runnable) () -> { -} : (Runnable) System.out::println); +} : System.out::println); + final @lombok.val java.lang.Runnable foo1 = ((System.currentTimeMillis() > 0) ? (Runnable) System.out::println : System.out::println); + final @lombok.val java.util.function.Function foo2 = ((System.currentTimeMillis() < 0) ? (java.util.function.Function) (<no type> r) -> "" : (<no type> r) -> System.currentTimeMillis()); + java.util.function.Function foo3 = ((System.currentTimeMillis() < 0) ? (java.util.function.Function) (<no type> r) -> "" : (<no type> r) -> System.currentTimeMillis()); + final @lombok.val java.util.function.Function<java.lang.String, java.lang.String> foo4 = ((System.currentTimeMillis() < 0) ? (java.util.function.Function<String, String>) (<no type> r) -> "" : (<no type> r) -> String.valueOf(System.currentTimeMillis())); } }
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/ValWeirdTypes.java b/test/transform/resource/after-ecj/ValWeirdTypes.java index 9f448db9..e98b9753 100644 --- a/test/transform/resource/after-ecj/ValWeirdTypes.java +++ b/test/transform/resource/after-ecj/ValWeirdTypes.java @@ -63,8 +63,14 @@ public class ValWeirdTypes<Z> { final @val int singleInt = copy[0]; } public void arraysAsList() { - final @val java.util.List<java.lang.Class<? extends java.lang.Object>> x = Arrays.asList(String.class, BigDecimal.class); - for (final @val java.lang.Class<? extends java.lang.Object> y : x) + final @val java.util.List<java.lang.Class<? extends java.io.Serializable>> x = Arrays.asList(String.class, BigDecimal.class); + for (final @val java.lang.Class<? extends java.io.Serializable> y : x) + { + } + } + public @SuppressWarnings("all") void arraysAsList2() { + final @val java.util.List<java.lang.Class<? extends java.lang.Comparable>> x = Arrays.asList(String.class, BigDecimal.class, Comparable.class); + for (final @val java.lang.Class<? extends java.lang.Comparable> y : x) { } } diff --git a/test/transform/resource/before/BuilderComplex.java b/test/transform/resource/before/BuilderComplex.java index c13f5877..46f62721 100644 --- a/test/transform/resource/before/BuilderComplex.java +++ b/test/transform/resource/before/BuilderComplex.java @@ -1,3 +1,4 @@ +//CONF: lombok.builder.className = Test*Name import java.util.List; import lombok.Builder; diff --git a/test/transform/resource/before/BuilderCustomName.java b/test/transform/resource/before/BuilderCustomName.java new file mode 100644 index 00000000..d5709e63 --- /dev/null +++ b/test/transform/resource/before/BuilderCustomName.java @@ -0,0 +1,7 @@ +//CONF: lombok.builder.className = SimpleTestBuilder +import java.util.List; + +@lombok.experimental.SuperBuilder +class BuilderCustomName<T> { + private final int field; +} diff --git a/test/transform/resource/before/BuilderJavadoc.java b/test/transform/resource/before/BuilderJavadoc.java index c2e0a6e0..390e2096 100644 --- a/test/transform/resource/before/BuilderJavadoc.java +++ b/test/transform/resource/before/BuilderJavadoc.java @@ -4,7 +4,7 @@ import java.util.List; class BuilderJavadoc<T> { /** * basic gets only a builder setter. - * @see #getsetwith + * @see #getsetwith * @param tag is moved to the setter. * @return tag is removed from the setter. */ @@ -49,6 +49,5 @@ class BuilderJavadoc<T> { this.predefWithJavadoc = x * 100; return this; } - } - + } } diff --git a/test/transform/resource/before/EqualsAndHashCodeAnnotated.java b/test/transform/resource/before/EqualsAndHashCodeAnnotated.java new file mode 100644 index 00000000..d672b982 --- /dev/null +++ b/test/transform/resource/before/EqualsAndHashCodeAnnotated.java @@ -0,0 +1,19 @@ +//version 8 +import java.lang.annotation.*; + +@lombok.EqualsAndHashCode +class EqualsAndHashCodeAnnotated { + @Annotated int primitive; + @Annotated Object object; + + int @Annotated [] primitiveValues; + int @Annotated [] @Annotated [] morePrimitiveValues; + + Integer @Annotated [] objectValues; + Integer @Annotated [] @Annotated [] moreObjectValues; + + @Target(ElementType.TYPE_USE) + @Retention(RetentionPolicy.SOURCE) + @interface Annotated { + } +} diff --git a/test/transform/resource/before/ValInLambda.java b/test/transform/resource/before/ValInLambda.java index 2c2a5942..a5364f8e 100644 --- a/test/transform/resource/before/ValInLambda.java +++ b/test/transform/resource/before/ValInLambda.java @@ -5,6 +5,7 @@ import lombok.val; class ValInLambda { Runnable foo = (Runnable) () -> { val i = 1; + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; }; public void easyLambda() { @@ -18,4 +19,10 @@ class ValInLambda { val i = 1; }; } + + public void easyLubLambda() { + Runnable foo = (Runnable) () -> { + lombok.val fooInner = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + }; + } } diff --git a/test/transform/resource/before/ValLambda.java b/test/transform/resource/before/ValLambda.java index 51c4fba1..5c9c4a43 100644 --- a/test/transform/resource/before/ValLambda.java +++ b/test/transform/resource/before/ValLambda.java @@ -1,5 +1,13 @@ // version 8: class ValLambda { + + static { + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + } + { + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + } + public void easyLambda() { lombok.val foo = (Runnable)()-> {}; } @@ -10,11 +18,10 @@ class ValLambda { } public void easyLubLambda() { - lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : (Runnable)System.out::println; + lombok.val foo = (System.currentTimeMillis() > 0) ? (Runnable)()-> {} : System.out::println; + lombok.val foo1 = (System.currentTimeMillis() > 0) ? (Runnable)System.out::println : System.out::println; + lombok.val foo2 = (System.currentTimeMillis() < 0) ? (java.util.function.Function) r -> "" : r -> System.currentTimeMillis(); + java.util.function.Function foo3 = (System.currentTimeMillis() < 0) ? (java.util.function.Function) r -> "" : r -> System.currentTimeMillis(); + lombok.val foo4 = (System.currentTimeMillis() < 0) ? (java.util.function.Function<String, String>) r -> "" : r -> String.valueOf(System.currentTimeMillis()); } - -// public void castLubLambda() { -// Runnable foo = (Runnable) ((System.currentTimeMillis() > 0) ? () -> {} : System.out::println); -// lombok.val foo = (Runnable) ((System.currentTimeMillis() > 0) ? () -> {} : System.out::println); -// } } diff --git a/test/transform/resource/before/ValWeirdTypes.java b/test/transform/resource/before/ValWeirdTypes.java index 4ea1b5d4..157ffc76 100644 --- a/test/transform/resource/before/ValWeirdTypes.java +++ b/test/transform/resource/before/ValWeirdTypes.java @@ -72,4 +72,12 @@ public class ValWeirdTypes<Z> { } } + + @SuppressWarnings("all") + public void arraysAsList2() { + val x = Arrays.asList(String.class, BigDecimal.class, Comparable.class); + for (val y : x) { + + } + } }
\ No newline at end of file diff --git a/test/transform/resource/messages-ecj/ValLambda.java.messages b/test/transform/resource/messages-ecj/ValLambda.java.messages new file mode 100644 index 00000000..e6940434 --- /dev/null +++ b/test/transform/resource/messages-ecj/ValLambda.java.messages @@ -0,0 +1,2 @@ +23 Function is a raw type. References to generic type Function<T,R> should be parameterized +24 Function is a raw type. References to generic type Function<T,R> should be parameterized
\ No newline at end of file diff --git a/website/resources/css/custom.css b/website/resources/css/custom.css index 6774a7d5..bd838df5 100644 --- a/website/resources/css/custom.css +++ b/website/resources/css/custom.css @@ -1,39 +1,94 @@ .importantNotification { - background-color: #FFEBCD; - border-radius: 20px; - padding: 10px; - margin: 10px; + background-color: #FFEBCD; + border-radius: 20px; + padding: 10px; + margin: 10px; } -#clickForVideo { - padding: 20px 30px; - background-color: #DDD; - cursor: pointer; - margin-left: auto; - margin-right: auto; - margin-bottom: 40px; +.tidelift-link-inline { + border-radius: 18px; + background-color: #626980; + background-color: #626980; + background-image: url('/img/tidelift-mark.png'); + background-repeat: no-repeat; + background-position: 6px; + background-size: 12px; + padding: 2px 8px 2px 26px; + color: white; } -.tidelift-para { - margin-top: 10px; +.tidelift-link { + border-bottom-left-radius: 18px; + border-top-left-radius: 18px; + background-color: #626980; + box-sizing: border-box; + color: white; + display: flex; + top: 46px; + right: 0px; + position: absolute; + background-image: url('/img/tidelift-mark.png'); + background-repeat: no-repeat; + background-position: 10px; + background-size: 12px; + padding: 6px 12px 6px 28px; +} + +.tidelift-link:hover, .tidelift-link-inline:hover { + color: white; } #tideliftlink { margin-left: 2px; padding: 4px 6px 4px 20px; - background-image: url('/img/tidelift-mark.png'); - background-repeat: no-repeat; - background-position: 4px; - background-size: 12px; background-color: #4b5168; border-radius: 5px; color: white; } +#clickForVideo { + padding: 20px 30px; + background-color: #DDD; + cursor: pointer; + margin-left: auto; + margin-right: auto; + margin-bottom: 40px; +} + pre { text-align: left; } +.tideliftb { + border-radius: 4px; + border: 2px solid #D9230F; + font-size: 28px; + width: 330px; + line-height: 48px; + display: inline-block; + margin: 16px 0; + text-align: center; +} + +.tideliftb1 { + background-color: white; + float: left; + color: #D9230F; +} + +.tideliftb1:hover { + color: #D9230F; +} + +.tideliftb2 { + background-color: #D9230F; + color: #FCFCFC; +} + +.tideliftb2:hover { + color: #FCFCFC; +} + .buttonLike { cursor: pointer; background: -webkit-linear-gradient(top, #FFFEF7, #CFCEC7); @@ -63,6 +118,10 @@ pre { margin-top: 20px; } +.tidelift { + font-size: 16px; +} + .formErr { color: #FF7777; } diff --git a/website/resources/img/projectlombok-tidelift-mix-orig.png b/website/resources/img/projectlombok-tidelift-mix-orig.png Binary files differnew file mode 100644 index 00000000..c3521b35 --- /dev/null +++ b/website/resources/img/projectlombok-tidelift-mix-orig.png diff --git a/website/resources/img/projectlombok-tidelift-mix.png b/website/resources/img/projectlombok-tidelift-mix.png Binary files differnew file mode 100644 index 00000000..082570d3 --- /dev/null +++ b/website/resources/img/projectlombok-tidelift-mix.png diff --git a/website/resources/js/main.js b/website/resources/js/main.js index eaaf2df5..3d18b996 100644 --- a/website/resources/js/main.js +++ b/website/resources/js/main.js @@ -37,7 +37,7 @@ if (self.data("clc")) return; var href = self.attr("href"); self.data("clc", true); - if (!href || href.substr(0, 4) === "http" || href === "/api/" || href === "/" || href === "/supporters" || href === "/order-license") return; + if (!href || href.substr(0, 4) === "http" || href.substr(0, 1) === "#" || href === "/api/" || href === "/" || href === "/supporters" || href === "/order-license") return; var ext = href.substr(href.length - 4, 4); if (ext === ".xml" || ext === ".jar" || ext === ".pdf") return; self.on("click", function(evt) { diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html index 4fe416ee..af1ffd3a 100644 --- a/website/templates/features/Builder.html +++ b/website/templates/features/Builder.html @@ -160,6 +160,10 @@ public class JacksonExample { <@f.confKeys> <dt> + <code>lombok.builder.className</code> = [a java identifier with an optional star to indicate where the return type name goes] (default: <code>*Builder</code>) + </dt><dd> + Unless you explicitly pick the builder's class name with the <code>builderClassName</code> parameter, this name is chosen; any star in the name is replaced with the relevant return type. + </dd><dt> <code>lombok.builder.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set) </dt><dd> Lombok will flag any usage of <code>@Builder</code> as a warning or error if configured. diff --git a/website/templates/features/_features.html b/website/templates/features/_features.html index f602b95b..f54a8fca 100644 --- a/website/templates/features/_features.html +++ b/website/templates/features/_features.html @@ -65,6 +65,7 @@ <#macro scaffold title logline load=[]> <@main.scaffold load title> + <a class="tidelift-link" href="/tidelift">Get Lombok for Enterprise</a> <div class="page-header top5" id="featureContent"> <div class="row text-center"> <div class="header-group"> diff --git a/website/templates/features/experimental/SuperBuilder.html b/website/templates/features/experimental/SuperBuilder.html index c68e28ca..5676b60c 100644 --- a/website/templates/features/experimental/SuperBuilder.html +++ b/website/templates/features/experimental/SuperBuilder.html @@ -52,6 +52,10 @@ <@f.confKeys> <dt> + <code>lombok.builder.className</code> = [a java identifier with an optional star to indicate where the return type name goes] (default: <code>*Builder</code>) + </dt><dd> + This is the name of the generated builder class; any star in the name is replaced with the relevant return type. Note that the parent class must also have the same setting (the entire type hierarchy annoated with <code>@SuperBuilder</code> needs the same setting). + </dd><dt> <code>lombok.superBuilder.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set) </dt><dd> Lombok will flag any usage of <code>@SuperBuilder</code> as a warning or error if configured. diff --git a/website/templates/features/experimental/index.html b/website/templates/features/experimental/index.html index ba830ab5..112d30c4 100644 --- a/website/templates/features/experimental/index.html +++ b/website/templates/features/experimental/index.html @@ -2,6 +2,7 @@ <#import "../_features.html" as f> <@main.scaffold title="Experimental"> + <a class="tidelift-link" href="/tidelift">Get Lombok for Enterprise</a> <div class="page-header top5"> <div class="row text-center"> <@main.h1 title="Lombok experimental features" /> diff --git a/website/templates/features/index.html b/website/templates/features/index.html index cd4c9e26..06b47c0b 100644 --- a/website/templates/features/index.html +++ b/website/templates/features/index.html @@ -1,6 +1,7 @@ <#import "../_scaffold.html" as main> <@main.scaffold title="Stable"> + <a class="tidelift-link" href="/tidelift">Get Lombok for Enterprise</a> <div class="page-header top5"> <div class="row text-center"> <@main.h1 title="Lombok features" /> diff --git a/website/templates/main.html b/website/templates/main.html index 03073436..be8a3bd9 100644 --- a/website/templates/main.html +++ b/website/templates/main.html @@ -1,5 +1,6 @@ <#import "/_scaffold.html" as main> <@main.scaffold load=["/js/supporters.js"]> + <a class="tidelift-link" href="/tidelift">Get Lombok for Enterprise</a> <div class="page-header top5"> <div class="row text-center"> <@main.h1 title="Project Lombok" /> @@ -33,8 +34,5 @@ <h2 class="introText" hidden="hidden">Project Lombok is <a href="/supporters">powered by</a>:</h2> <div class="supporterFooter" hidden="hidden"><a class="buttonLike" href="/order-license-info">I want to support Project Lombok too!</a></div> </div> - <div class="row text-center tidelift-para"> - Looking for professional support of Project Lombok? Lombok is now part of a <a id="tideliftlink" href="https://tidelift.com/subscription/pkg/maven-org-projectlombok-lombok?utm_source=lombok&utm_medium=referral&utm_campaign=website">Tidelift subscription</a> - </div> </div> </@main.scaffold> diff --git a/website/templates/order-license-info.html b/website/templates/order-license-info.html index 735bd4cb..f5839c0a 100644 --- a/website/templates/order-license-info.html +++ b/website/templates/order-license-info.html @@ -9,7 +9,7 @@ <p> Tidelift offers professional support of open source tools. When you have a Tidelift subscription, they will help you inventory all the various open source tools and libraries you use, give one central location to check compliance, and a single channel for release notes and security advisories. The bulk of the tidelift subscription fee is redistributed to major open source projects, and Project Lombok is one of those 'lifted' projects. Therefore, your Tidelift subscription helps maintain Project Lombok! </p><p> - We recommend a <a id="tideliftlink" href="https://tidelift.com/subscription/pkg/maven-org-projectlombok-lombok?utm_source=lombok&utm_medium=referral&utm_campaign=website">Tidelift subscription</a> to any corporation that uses Project Lombok. + We recommend a <a class="tidelift-link-inline" href="https://tidelift.com/subscription/pkg/maven-org-projectlombok-lombok?utm_source=lombok&utm_medium=referral&utm_campaign=orderdonate">Tidelift subscription</a> to any corporation that uses Project Lombok. </div> <div class="row text-center"> <h2>Order a professional or enterprise license</h2> diff --git a/website/templates/tidelift.html b/website/templates/tidelift.html new file mode 100644 index 00000000..7f0ab88b --- /dev/null +++ b/website/templates/tidelift.html @@ -0,0 +1,34 @@ +<#import "/_scaffold.html" as main> + +<@main.scaffold title="Project Lombok for Enterprise"> + <div class="page-header top5 tidelift"> + <div class="row text-center"> + <h2>Available as part of the Tidelift Subscription</h2> + </div> + <div class="row"> + <img src="/img/projectlombok-tidelift-mix.png" width="200" height="150" class="pull-right" alt="tidelift+lombok" /> + <p> + Project Lombok and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. + </p><p> + If you want the flexibility of open source and the confidence of commercial-grade software, this is for you. + </p> + </div> + <div class="row text-center"> + <a class="tideliftb tideliftb1" href="https://tidelift.com/subscription/pkg/maven-org-projectlombok-lombok?utm_source=lombok&utm_medium=referral&utm_campaign=enterprise">LEARN MORE</a> <a class="tideliftb tideliftb2" href="https://tidelift.com/subscription/request-a-demo?utm_source=lombok&utm_medium=referral&utm_campaign=enterprise">REQUEST A DEMO</a> + </div> + <div class="row text-center"> + <h2>The Tidelift Subscription manages your dependencies for you</h2> + </div> + <div class="row"> + <p> + <ul> + <li>Get the tools you need to continuously catalog and understand the open source software that your application depends on.</li> + <li>Your subscription helps pay the open source maintainers of the exact packages you use to ensure they meet the standards you require.</li> + <li>Address issues proactively, with tools that scan for new security, licensing, and maintenance issues, and alert our participating open source maintainers so they can resolve them on your behalf.</li> + <li>Measure and improve your open source dependencies' health—which improves your app’s health—and get a short list of high-impact steps your team can take to improve them even more.</li> + <li>Get commercial assurances that don't come for free with open source packages, like intellectual property indemnification and support under a service level agreement. You expect these guarantees from proprietary software, and you can have them when using open source as well.</li> + </ul> + The end result? All of the capabilities you expect from commercial-grade software, for the full breadth of open source you use. That means less time grappling with esoteric open source trivia, and more time building your own applications—and your business. + </div> + </div> +</@main.scaffold> |