aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/changelog.markdown4
-rw-r--r--src/core/lombok/Builder.java8
-rw-r--r--src/core/lombok/ConfigurationKeys.java15
-rw-r--r--src/core/lombok/Generated.java3
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java43
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleSuperBuilder.java13
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java42
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java25
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java39
-rw-r--r--src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSetSingularizer.java16
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java45
-rw-r--r--src/core/lombok/javac/handlers/HandleDelegate.java3
-rw-r--r--src/core/lombok/javac/handlers/HandleFieldNameConstants.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java9
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java3
-rw-r--r--src/core/lombok/javac/handlers/JavacSingularsRecipes.java79
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java27
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java28
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java4
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java38
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilSetSingularizer.java6
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java4
-rwxr-xr-xsrc/delombok/lombok/delombok/Delombok.java13
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java69
-rw-r--r--src/delombok/lombok/delombok/ant/DelombokTask.java4
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchVal.java14
-rw-r--r--src/installer/lombok/installer/OsUtils.java4
-rw-r--r--src/installer/lombok/installer/WindowsDriveInfo-i386.binary (renamed from src/installer/lombok/installer/WindowsDriveInfo-i386.dll)bin14472 -> 14472 bytes
-rw-r--r--src/installer/lombok/installer/WindowsDriveInfo-x86_64.binary (renamed from src/installer/lombok/installer/WindowsDriveInfo-x86_64.dll)bin66806 -> 66806 bytes
-rw-r--r--src/utils/lombok/javac/JavacTreeMaker.java6
-rw-r--r--src/utils/lombok/permit/Permit.java27
-rw-r--r--test/core/src/lombok/DirectoryRunner.java2
-rw-r--r--test/pretty/resource/after/Java11Var.java (renamed from test/pretty/resource/after/Java11Var.javva)0
-rw-r--r--test/pretty/resource/after/Switch11.java11
-rw-r--r--test/pretty/resource/after/Switch12.java28
-rw-r--r--test/pretty/resource/before/Switch11.java12
-rw-r--r--test/pretty/resource/before/Switch12.java30
-rw-r--r--test/transform/resource/after-delombok/BuilderSimple.java4
-rw-r--r--test/transform/resource/after-delombok/FieldNameConstantsUppercased.java12
-rw-r--r--test/transform/resource/after-delombok/SuperBuilderWithGenericsAndToBuilder.java53
-rw-r--r--test/transform/resource/after-delombok/ValDelegateMethodReference.java65
-rw-r--r--test/transform/resource/after-ecj/BuilderSimple.java6
-rw-r--r--test/transform/resource/after-ecj/FieldNameConstantsUppercased.java23
-rw-r--r--test/transform/resource/after-ecj/SuperBuilderWithGenericsAndToBuilder.java60
-rw-r--r--test/transform/resource/after-ecj/ValDelegateMethodReference.java58
-rw-r--r--test/transform/resource/before/BuilderSimple.java2
-rw-r--r--test/transform/resource/before/FieldNameConstantsUppercased.java12
-rw-r--r--test/transform/resource/before/SuperBuilderWithGenericsAndToBuilder.java6
-rw-r--r--test/transform/resource/before/ValDelegateMethodReference.java35
-rw-r--r--website/extra/htaccess4
-rw-r--r--website/resources/js/main.js16
-rw-r--r--website/templates/credits.html2
-rw-r--r--website/templates/features/Builder.html9
-rw-r--r--website/templates/features/Value.html2
-rw-r--r--website/templates/features/configuration.html4
-rw-r--r--website/templates/features/experimental/FieldNameConstants.html8
-rw-r--r--website/templates/main.html2
-rw-r--r--website/templates/presentations/7lessons.html25
61 files changed, 863 insertions, 269 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index 64ddcc7f..acaa74de 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,12 +2,16 @@ Lombok Changelog
----------------
### v1.18.7 "Edgy Guinea Pig"
+* 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).
+* 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)
* BUGFIX: Delombok now delomboks java10's own `var` as `var` and not as the actual underlying type. [Issue #2049](https://github.com/rzwitserloot/lombok/issues/2049)
* BUGFIX: If you use `@Builder` and manually write the `build()` method in your builder class, javac would error out instead of deferring to your implementation. [Issue #2050](https://github.com/rzwitserloot/lombok/issues/2050) [Issue #2061](https://github.com/rzwitserloot/lombok/issues/2061)
+* 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.
### v1.18.6 (February 12th, 2019)
diff --git a/src/core/lombok/Builder.java b/src/core/lombok/Builder.java
index c83b3670..a60af9ee 100644
--- a/src/core/lombok/Builder.java
+++ b/src/core/lombok/Builder.java
@@ -147,6 +147,14 @@ public @interface Builder {
boolean toBuilder() default false;
/**
+ * Sets the access level of the generated builder class. By default, generated builder classes are {@code public}.
+ * Note: This does nothing if you write your own builder class (we won't change its access level).
+ *
+ * @return The builder class will be generated with this access modifier.
+ */
+ AccessLevel access() default lombok.AccessLevel.PUBLIC;
+
+ /**
* Put on a field (in case of {@code @Builder} on a type) or a parameter (for {@code @Builder} on a constructor or static method) to
* indicate how lombok should obtain a value for this field or parameter given an instance; this is only relevant if {@code toBuilder} is {@code true}.
*
diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index 2b406dbe..84b594f5 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -51,7 +51,7 @@ public class ConfigurationKeys {
*
* If {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated, unless {@code lombok.addJavaxGeneratedAnnotation} is set.
* <br>
- * <em>BREAKING CHANGE</em>: Starting with lombok v2.0.0, defaults to {@code false} instead of {@code true}, as this annotation is broken in JDK9.
+ * <em>BREAKING CHANGE</em>: Starting with lombok v1.16.20, defaults to {@code false} instead of {@code true}, as this annotation is broken in JDK9.
*
* @see ConfigurationKeys#ADD_JAVAX_GENERATED_ANNOTATIONS
* @see ConfigurationKeys#ADD_LOMBOK_GENERATED_ANNOTATIONS
@@ -65,7 +65,7 @@ public class ConfigurationKeys {
*
* If {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated.
* <br>
- * <em>BREAKING CHANGE</em>: Starting with lombok v2.0.0, defaults to {@code false} instead of {@code true}, as this annotation is broken in JDK9.
+ * <em>BREAKING CHANGE</em>: Starting with lombok v1.16.20, defaults to {@code false} instead of {@code true}, as this annotation is broken in JDK9.
*/
public static final ConfigurationKey<Boolean> ADD_JAVAX_GENERATED_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.addJavaxGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: follow lombok.addGeneratedAnnotation).") {};
@@ -103,7 +103,7 @@ public class ConfigurationKeys {
* NB: GWT projects, and probably android projects, should explicitly set this key to {@code true} for the entire project.
*
* <br>
- * <em>BREAKING CHANGE</em>: Starting with lombok v2.0.0, defaults to {@code false} instead of {@code true}, as {@code @ConstructorProperties} requires extra modules in JDK9.
+ * <em>BREAKING CHANGE</em>: Starting with lombok v1.16.20, defaults to {@code false} instead of {@code true}, as {@code @ConstructorProperties} requires extra modules in JDK9.
*
* @see ConfigurationKeys#ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES
* @deprecated Since version 2.0, use {@link #ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES} instead.
@@ -543,6 +543,13 @@ public class ConfigurationKeys {
*/
public static final ConfigurationKey<String> FIELD_NAME_CONSTANTS_INNER_TYPE_NAME = new ConfigurationKey<String>("lombok.fieldNameConstants.innerTypeName", "The default name of the inner type generated by @FieldNameConstants. (default: 'Fields').") {};
+ /**
+ * lombok configuration: {@code lombok.fieldNameConstants.uppercase} = {@code true} | {@code false}.
+ *
+ * If true, names of constants generated by {@code @FieldNameConstants} will be UPPER_CASED_LIKE_A_CONSTANT. (Default: {@code false}).
+ */
+ public static final ConfigurationKey<Boolean> FIELD_NAME_CONSTANTS_UPPERCASE = new ConfigurationKey<Boolean>("lombok.fieldNameConstants.uppercase", "The default name of the constants inside the inner type generated by @FieldNameConstants follow the variable name precisely. If this config key is true, lombok will uppercase them as best it can. (default: false).") {};
+
// ----- Wither -----
/**
diff --git a/src/core/lombok/Generated.java b/src/core/lombok/Generated.java
index b99a1b58..216ab143 100644
--- a/src/core/lombok/Generated.java
+++ b/src/core/lombok/Generated.java
@@ -33,7 +33,8 @@ import java.lang.annotation.Target;
* <p>
* NB: As of v1.16.2 which introduces this annotation, lombok doesn't actually add this annotation; we're setting
* it up so that lombok jars in widespread use start having this, which will make it easier to actually apply it
- * later on.
+ * later on. By adding {@code lombok.addLombokGeneratedAnnotation = true} to {@code lombok.config} you can already
+ * get this behavior.
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index 81ddbd0a..a8a780d6 100755
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -58,6 +58,7 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import lombok.AccessLevel;
import lombok.core.LombokImmutableList;
import lombok.core.SpiLoadUtil;
import lombok.core.TypeLibrary;
@@ -234,7 +235,7 @@ public class EclipseSingularsRecipes {
* If you need more control over the return type and value, use
* {@link #generateMethods(SingularData, boolean, EclipseNode, boolean, TypeReferenceMaker, StatementMaker)}.
*/
- public void generateMethods(SingularData data, boolean deprecate, final EclipseNode builderType, boolean fluent, final boolean chain) {
+ public void generateMethods(SingularData data, boolean deprecate, final EclipseNode builderType, boolean fluent, final boolean chain, AccessLevel access) {
TypeReferenceMaker returnTypeMaker = new TypeReferenceMaker() {
@Override public TypeReference make() {
return chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
@@ -247,14 +248,14 @@ public class EclipseSingularsRecipes {
}
};
- generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker);
+ generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
}
/**
* Generates the singular, plural, and clear methods for the given {@link SingularData}.
* Uses the given {@code returnTypeMaker} and {@code returnStatementMaker} for the generated methods.
*/
- public abstract void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker);
+ public abstract void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access);
public abstract void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName, String builderVariable);
@@ -394,5 +395,8 @@ public class EclipseSingularsRecipes {
return new SingleNameReference(builderVariable.toCharArray(), 0);
}
}
+
+ protected abstract char[][] getEmptyMakerReceiver(String targetFqn);
+ protected abstract char[] getEmptyMakerSelector(String targetFqn);
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 7a831f3d..4659e9a3 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -157,6 +157,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
long p = (long) ast.sourceStart << 32 | ast.sourceEnd;
Builder builderInstance = annotation.getInstance();
+ AccessLevel accessForOuters = builderInstance.access();
+ if (accessForOuters == null) accessForOuters = AccessLevel.PUBLIC;
+ if (builderInstance.access() == AccessLevel.NONE) {
+ annotationNode.addError("AccessLevel.NONE is not valid here");
+ accessForOuters = AccessLevel.PUBLIC;
+ }
+ AccessLevel accessForInners = accessForOuters == AccessLevel.PROTECTED ? AccessLevel.PUBLIC : accessForOuters;
// These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true);
@@ -408,7 +415,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
EclipseNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
- builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast);
+ builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast, accessForOuters);
} else {
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
if (isStatic && (builderTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
@@ -469,14 +476,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
for (BuilderFieldData bfd : builderFields) {
- makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
+ makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain, accessForInners);
}
{
MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
if (methodExists == MemberExistsResult.NOT_EXISTS) {
- MethodDeclaration md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast);
+ MethodDeclaration md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast, accessForInners);
if (md != null) injectMethod(builderType, md);
}
}
@@ -499,7 +506,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
if (generateBuilderMethod) {
- MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast);
+ MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast, accessForOuters);
if (md != null) injectMethod(tdParent, md);
}
@@ -516,7 +523,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
tps[i].name = typeArgsForToBuilder.get(i);
}
}
- MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast);
+ MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
if (md != null) injectMethod(tdParent, md);
}
@@ -529,13 +536,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
- private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source) {
+ private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source, AccessLevel access) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = methodName.toCharArray();
- out.modifiers = ClassFileConstants.AccPublic;
+ out.modifiers = toEclipseModifier(access);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
AllocationExpression invoke = new AllocationExpression();
@@ -632,7 +639,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return decl;
}
- public MethodDeclaration generateBuildMethod(EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source) {
+ public MethodDeclaration generateBuildMethod(EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source, AccessLevel access) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
List<Statement> statements = new ArrayList<Statement>();
@@ -677,7 +684,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
statements.add(new Assignment(thisUnclean, new TrueLiteral(0, 0), 0));
}
- out.modifiers = ClassFileConstants.AccPublic;
+ out.modifiers = toEclipseModifier(access);
out.selector = name.toCharArray();
out.thrownExceptions = copyTypes(thrownExceptions);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
@@ -736,13 +743,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return out;
}
- public MethodDeclaration generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
+ public MethodDeclaration generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source, AccessLevel access) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.selector = builderMethodName.toCharArray();
- out.modifiers = ClassFileConstants.AccPublic;
+ out.modifiers = toEclipseModifier(access);
if (isStatic) out.modifiers |= ClassFileConstants.AccStatic;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
@@ -795,16 +802,16 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
private static final AbstractMethodDeclaration[] EMPTY = {};
- public void makeSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain) {
+ public void makeSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access) {
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
- makeSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations);
+ makeSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access);
} else {
- bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, fluent, chain);
+ bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, fluent, chain, access);
}
}
- private void makeSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations) {
+ private void makeSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations, AccessLevel access) {
TypeDeclaration td = (TypeDeclaration) builderType.get();
AbstractMethodDeclaration[] existing = td.methods;
if (existing == null) existing = EMPTY;
@@ -820,16 +827,16 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName());
- MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, chain, ClassFileConstants.AccPublic,
+ MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, chain, toEclipseModifier(access),
sourceNode, Collections.<Annotation>emptyList(), annotations != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annotations)) : Collections.<Annotation>emptyList());
injectMethod(builderType, setter);
}
- public EclipseNode makeBuilderClass(boolean isStatic, EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source) {
+ public EclipseNode makeBuilderClass(boolean isStatic, EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, ASTNode source, AccessLevel access) {
TypeDeclaration parent = (TypeDeclaration) tdParent.get();
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
- builder.modifiers |= ClassFileConstants.AccPublic;
+ builder.modifiers |= toEclipseModifier(access);
if (isStatic) builder.modifiers |= ClassFileConstants.AccStatic;
builder.typeParameters = copyTypeParams(typeParams, source);
builder.name = builderClassName.toCharArray();
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
index 1caccd59..574c1f41 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
@@ -47,6 +47,7 @@ import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
+import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -55,7 +56,7 @@ import lombok.experimental.FieldNameConstants;
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldNameConstants> {
- public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit) {
+ public void generateFieldNameConstantsForType(EclipseNode typeNode, EclipseNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit, boolean uppercase) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
@@ -76,7 +77,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
if (qualified.isEmpty()) {
errorNode.addWarning("No fields qualify for @FieldNameConstants, therefore this annotation does nothing");
} else {
- createInnerTypeFieldNameConstants(typeNode, errorNode, errorNode.get(), level, qualified, asEnum, innerTypeName);
+ createInnerTypeFieldNameConstants(typeNode, errorNode, errorNode.get(), level, qualified, asEnum, innerTypeName, uppercase);
}
}
@@ -112,11 +113,13 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
String innerTypeName = annotationInstance.innerTypeName();
if (innerTypeName.isEmpty()) innerTypeName = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_INNER_TYPE_NAME);
if (innerTypeName == null || innerTypeName.isEmpty()) innerTypeName = "Fields";
+ Boolean uppercase = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_UPPERCASE);
+ if (uppercase == null) uppercase = false;
- generateFieldNameConstantsForType(node, annotationNode, level, asEnum, innerTypeName, annotationInstance.onlyExplicitlyIncluded());
+ generateFieldNameConstantsForType(node, annotationNode, level, asEnum, innerTypeName, annotationInstance.onlyExplicitlyIncluded(), uppercase);
}
- private void createInnerTypeFieldNameConstants(EclipseNode typeNode, EclipseNode errorNode, ASTNode source, AccessLevel level, List<EclipseNode> fields, boolean asEnum, String innerTypeName) {
+ private void createInnerTypeFieldNameConstants(EclipseNode typeNode, EclipseNode errorNode, ASTNode source, AccessLevel level, List<EclipseNode> fields, boolean asEnum, String innerTypeName, boolean uppercase) {
if (fields.isEmpty()) return;
ASTVisitor generatedByVisitor = new SetGeneratedByVisitor(source);
@@ -169,6 +172,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
for (EclipseNode fieldNode : fields) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
char[] fName = field.name;
+ if (uppercase) fName = HandlerUtil.camelCaseToConstant(new String(fName)).toCharArray();
if (fieldExists(new String(fName), fieldsType) != MemberExistsResult.NOT_EXISTS) continue;
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 6f34eb30..3a387688 100755
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -108,7 +108,6 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
private static final char[] TO_BUILDER_METHOD_NAME = TO_BUILDER_METHOD_NAME_STRING.toCharArray();
private static final char[] FILL_VALUES_METHOD_NAME = "$fillValuesFrom".toCharArray();
private static final char[] FILL_VALUES_STATIC_METHOD_NAME = "$fillValuesFromInstanceIntoBuilder".toCharArray();
- private static final char[] EMPTY_LIST = "emptyList".toCharArray();
private static final char[] INSTANCE_VARIABLE_NAME = "instance".toCharArray();
private static final String BUILDER_VARIABLE_NAME_STRING = "b";
private static final char[] BUILDER_VARIABLE_NAME = BUILDER_VARIABLE_NAME_STRING.toCharArray();
@@ -741,10 +740,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
ms.arguments = tgt;
} else {
Expression ifNull = new EqualExpression(tgt[0], new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL);
- MessageSend emptyList = new MessageSend();
- emptyList.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Collections".toCharArray());
- emptyList.selector = EMPTY_LIST;
- ms.arguments = new Expression[] {new ConditionalExpression(ifNull, emptyList, tgt[1])};
+ MessageSend emptyCollection = new MessageSend();
+ emptyCollection.receiver = generateQualifiedNameRef(source, bfd.singularData.getSingularizer().getEmptyMakerReceiver(bfd.singularData.getTargetFqn()));
+ emptyCollection.selector = bfd.singularData.getSingularizer().getEmptyMakerSelector(bfd.singularData.getTargetFqn());
+ ms.arguments = new Expression[] {new ConditionalExpression(ifNull, emptyCollection, tgt[1])};
}
ms.receiver = new SingleNameReference(BUILDER_VARIABLE_NAME, 0);
ms.selector = setterName;
@@ -889,7 +888,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
generateSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode, bfd.annotations);
} else {
- bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker);
+ bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
}
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 40f01ee4..642ba9b7 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import lombok.AccessLevel;
import lombok.core.GuavaTypeMap;
import lombok.core.LombokImmutableList;
import lombok.core.handlers.HandlerUtil;
@@ -62,6 +63,9 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
+ protected static final char[] OF = {'o', 'f'};
+ protected static final char[][] CGCC = {{'c', 'o', 'm'}, {'g', 'o', 'o', 'g', 'l', 'e'}, {'c', 'o', 'm', 'm', 'o', 'n'}, {'c', 'o', 'l', 'l', 'e', 'c', 't'}};
+
protected String getSimpleTargetTypeName(SingularData data) {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
@@ -74,15 +78,23 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
protected char[][] makeGuavaTypeName(String simpleName, boolean addBuilder) {
char[][] tokenizedName = new char[addBuilder ? 6 : 5][];
- tokenizedName[0] = new char[] {'c', 'o', 'm'};
- tokenizedName[1] = new char[] {'g', 'o', 'o', 'g', 'l', 'e'};
- tokenizedName[2] = new char[] {'c', 'o', 'm', 'm', 'o', 'n'};
- tokenizedName[3] = new char[] {'c', 'o', 'l', 'l', 'e', 'c', 't'};
+ tokenizedName[0] = CGCC[0];
+ tokenizedName[1] = CGCC[1];
+ tokenizedName[2] = CGCC[2];
+ tokenizedName[3] = CGCC[3];
tokenizedName[4] = simpleName.toCharArray();
if (addBuilder) tokenizedName[5] = new char[] { 'B', 'u', 'i', 'l', 'd', 'e', 'r'};
return tokenizedName;
}
+ @Override protected char[] getEmptyMakerSelector(String targetFqn) {
+ return OF;
+ }
+
+ @Override protected char[][] getEmptyMakerReceiver(String targetFqn) {
+ return CGCC;
+ }
+
@Override public List<EclipseNode> generateFields(SingularData data, EclipseNode builderType) {
String simpleTypeName = getSimpleTargetTypeName(data);
char[][] tokenizedName = makeGuavaTypeName(simpleTypeName, true);
@@ -99,16 +111,16 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker) {
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType);
+ @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
+ void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
@@ -122,7 +134,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
injectMethod(builderType, md);
}
- void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
LombokImmutableList<String> suffixes = getArgumentSuffixes();
char[][] names = new char[suffixes.size()][];
for (int i = 0; i < suffixes.size(); i++) {
@@ -133,7 +145,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType));
@@ -166,10 +178,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType));
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 32b1f71f..73d6fe9b 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import lombok.AccessLevel;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.HandleNonNull;
@@ -90,21 +91,21 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker) {
+ @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
if (useGuavaInstead(builderType)) {
- guavaListSetSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker);
+ guavaListSetSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
return;
}
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType);
+ generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
+ private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
thisDotField.receiver = new ThisReference(0, 0);
@@ -123,10 +124,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
injectMethod(builderType, md);
}
- void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, false));
@@ -155,10 +156,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, false));
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
index 80d49fe7..7ea04821 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -55,6 +55,16 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
return LombokImmutableList.of("java.util.List", "java.util.Collection", "java.lang.Iterable");
}
+ private static final char[] EMPTY_LIST = {'e', 'm', 'p', 't', 'y', 'L', 'i', 's', 't'};
+
+ @Override protected char[][] getEmptyMakerReceiver(String targetFqn) {
+ return JAVA_UTIL_COLLECTIONS;
+ }
+
+ @Override protected char[] getEmptyMakerSelector(String targetFqn) {
+ return EMPTY_LIST;
+ }
+
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName, String builderVariable) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, statements, targetVariableName, builderVariable);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index b24bf97f..b642522f 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -52,6 +52,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.mangosdk.spi.ProviderFor;
+import lombok.AccessLevel;
import lombok.core.LombokImmutableList;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
@@ -67,6 +68,20 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
}
+ private static final char[] EMPTY_SORTED_MAP = {'e', 'm', 'p', 't', 'y', 'S', 'o', 'r', 't', 'e', 'd', 'M', 'a', 'p'};
+ private static final char[] EMPTY_NAVIGABLE_MAP = {'e', 'm', 'p', 't', 'y', 'N', 'a', 'v', 'i', 'g', 'a', 'b', 'l', 'e', 'M', 'a', 'p'};
+ private static final char[] EMPTY_MAP = {'e', 'm', 'p', 't', 'y', 'M', 'a', 'p'};
+
+ @Override protected char[][] getEmptyMakerReceiver(String targetFqn) {
+ return JAVA_UTIL_COLLECTIONS;
+ }
+
+ @Override protected char[] getEmptyMakerSelector(String targetFqn) {
+ if (targetFqn.endsWith("SortedMap")) return EMPTY_SORTED_MAP;
+ if (targetFqn.endsWith("NavigableMap")) return EMPTY_NAVIGABLE_MAP;
+ return EMPTY_MAP;
+ }
+
@Override public List<char[]> listFieldsToBeGenerated(SingularData data, EclipseNode builderType) {
if (useGuavaInstead(builderType)) {
return guavaMapSingularizer.listFieldsToBeGenerated(data, builderType);
@@ -135,21 +150,21 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
return Arrays.asList(keyFieldNode, valueFieldNode);
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker) {
+ @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
if (useGuavaInstead(builderType)) {
- guavaMapSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker);
+ guavaMapSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
return;
}
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType);
+ generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType) {
+ private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
String pN = new String(data.getPluralName());
char[] keyFieldName = (pN + "$key").toCharArray();
@@ -179,10 +194,10 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
injectMethod(builderType, md);
}
- private void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ private void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
List<Statement> statements = new ArrayList<Statement>();
statements.add(createConstructBuilderVarIfNeeded(data, builderType, true));
@@ -236,10 +251,10 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- private void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) {
+ private void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- md.modifiers = ClassFileConstants.AccPublic;
+ md.modifiers = toEclipseModifier(access);
String pN = new String(data.getPluralName());
char[] keyFieldName = (pN + "$key").toCharArray();
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSetSingularizer.java
index 200e615e..2076ec7d 100644
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSetSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -37,6 +37,20 @@ public class EclipseJavaUtilSetSingularizer extends EclipseJavaUtilListSetSingul
return LombokImmutableList.of("java.util.Set", "java.util.SortedSet", "java.util.NavigableSet");
}
+ private static final char[] EMPTY_SORTED_SET = {'e', 'm', 'p', 't', 'y', 'S', 'o', 'r', 't', 'e', 'd', 'S', 'e', 't'};
+ private static final char[] EMPTY_NAVIGABLE_SET = {'e', 'm', 'p', 't', 'y', 'N', 'a', 'v', 'i', 'g', 'a', 'b', 'l', 'e', 'S', 'e', 't'};
+ private static final char[] EMPTY_SET = {'e', 'm', 'p', 't', 'y', 'S', 'e', 't'};
+
+ @Override protected char[][] getEmptyMakerReceiver(String targetFqn) {
+ return JAVA_UTIL_COLLECTIONS;
+ }
+
+ @Override protected char[] getEmptyMakerSelector(String targetFqn) {
+ if (targetFqn.endsWith("SortedSet")) return EMPTY_SORTED_SET;
+ if (targetFqn.endsWith("NavigableSet")) return EMPTY_NAVIGABLE_SET;
+ return EMPTY_SET;
+ }
+
@Override public void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName, String builderVariable) {
if (useGuavaInstead(builderType)) {
guavaListSetSingularizer.appendBuildCode(data, builderType, statements, targetVariableName, builderVariable);
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index d6fb9728..2eaba0fb 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -103,6 +103,13 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
handleFlagUsage(annotationNode, ConfigurationKeys.BUILDER_FLAG_USAGE, "@Builder");
Builder builderInstance = annotation.getInstance();
+ AccessLevel accessForOuters = builderInstance.access();
+ if (accessForOuters == null) accessForOuters = AccessLevel.PUBLIC;
+ if (accessForOuters == AccessLevel.NONE) {
+ annotationNode.addError("AccessLevel.NONE is not valid here");
+ accessForOuters = AccessLevel.PUBLIC;
+ }
+ AccessLevel accessForInners = accessForOuters == AccessLevel.PROTECTED ? AccessLevel.PUBLIC : accessForOuters;
// These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true);
@@ -355,7 +362,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
- builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast);
+ builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast, accessForOuters);
recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
} else {
JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
@@ -413,14 +420,14 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
for (BuilderFieldData bfd : builderFields) {
- makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
+ makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain, accessForInners);
}
{
MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
if (methodExists == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
+ JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning, accessForInners);
if (md != null) {
injectMethod(builderType, md);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
@@ -444,7 +451,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
if (generateBuilderMethod) {
- JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams);
+ JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams, accessForOuters);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null) injectMethod(tdParent, md);
}
@@ -464,7 +471,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
tps = lb.toList();
}
- JCMethodDecl md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast);
+ JCMethodDecl md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
if (md != null) {
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
injectMethod(tdParent, md);
@@ -513,7 +520,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
private static final String BUILDER_TEMP_VAR = "builder";
- private JCMethodDecl generateToBuilderMethod(String toBuilderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast) {
+ private JCMethodDecl generateToBuilderMethod(String toBuilderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access) {
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
JavacTreeMaker maker = type.getTreeMaker();
@@ -564,7 +571,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
statements.append(maker.Return(invoke));
}
JCBlock body = maker.Block(0, statements.toList());
- return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(toBuilderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ return maker.MethodDef(maker.Modifiers(toJavacModifier(access)), type.toName(toBuilderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
private JCMethodDecl generateCleanMethod(java.util.List<BuilderFieldData> builderFields, JavacNode type, JCTree source) {
@@ -579,7 +586,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, 0))));
JCBlock body = maker.Block(0, statements.toList());
- JCMethodDecl method = maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName("$lombokClean"), maker.Type(Javac.createVoidType(type.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ JCMethodDecl method = maker.MethodDef(maker.Modifiers(toJavacModifier(AccessLevel.PRIVATE)), type.toName("$lombokClean"), maker.Type(Javac.createVoidType(type.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
recursiveSetGeneratedBy(method, source, type.getContext());
return method;
/*
@@ -596,7 +603,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
*/
}
- private JCMethodDecl generateBuildMethod(JavacNode tdParent, boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning) {
+ private JCMethodDecl generateBuildMethod(JavacNode tdParent, boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning, AccessLevel access) {
JavacTreeMaker maker = type.getTreeMaker();
JCExpression call;
@@ -649,7 +656,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCBlock body = maker.Block(0, statements.toList());
- return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ return maker.MethodDef(maker.Modifiers(toJavacModifier(access)), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
}
public static JCMethodDecl generateDefaultProvider(Name methodName, JavacNode fieldNode, List<JCTypeParameter> params) {
@@ -664,7 +671,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return maker.MethodDef(maker.Modifiers(modifiers), methodName, cloneType(maker, field.vartype, field, fieldNode.getContext()), copyTypeParams(fieldNode, params), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
- public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) {
+ public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams, AccessLevel access) {
JavacTreeMaker maker = type.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
@@ -676,7 +683,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
- int modifiers = Flags.PUBLIC;
+ int modifiers = toJavacModifier(access);
if (isStatic) modifiers |= Flags.STATIC;
return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
@@ -720,16 +727,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, source, builderType.getContext());
}
- public void makeSetterMethodsForBuilder(JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain) {
+ public void makeSetterMethodsForBuilder(JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain, AccessLevel access) {
boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
- makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode);
+ makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access);
} else {
- fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain);
+ fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain, access);
}
}
- private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode) {
+ private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, AccessLevel access) {
Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
for (JavacNode child : builderType.down()) {
@@ -743,16 +750,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacTreeMaker maker = fieldNode.getTreeMaker();
- JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, List.<JCAnnotation>nil(), annosOnParam);
+ JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(access), deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, List.<JCAnnotation>nil(), annosOnParam);
recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext());
copyJavadoc(originalFieldNode, newMethod, CopyJavadoc.SETTER);
injectMethod(builderType, newMethod);
}
- public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast) {
+ public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast, AccessLevel access) {
JavacTreeMaker maker = tdParent.getTreeMaker();
- int modifiers = Flags.PUBLIC;
+ int modifiers = toJavacModifier(access);
if (isStatic) modifiers |= Flags.STATIC;
JCModifiers mods = maker.Modifiers(modifiers);
JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java
index baff7912..367b2cff 100644
--- a/src/core/lombok/javac/handlers/HandleDelegate.java
+++ b/src/core/lombok/javac/handlers/HandleDelegate.java
@@ -82,7 +82,7 @@ import lombok.javac.JavacTreeMaker;
import lombok.javac.ResolutionResetNeeded;
@ProviderFor(JavacAnnotationHandler.class)
-@HandlerPriority(65536) //2^16; to make sure that we also delegate generated methods.
+@HandlerPriority(HandleDelegate.HANDLE_DELEGATE_PRIORITY) //2^16; to make sure that we also delegate generated methods.
@ResolutionResetNeeded
public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
@@ -102,6 +102,7 @@ public class HandleDelegate extends JavacAnnotationHandler<Delegate> {
private static final String LEGALITY_OF_DELEGATE = "@Delegate is legal only on instance fields or no-argument instance methods.";
private static final String RECURSION_NOT_ALLOWED = "@Delegate does not support recursion (delegating to a type that itself has @Delegate members). Member \"%s\" is @Delegate in type \"%s\"";
+ public static final int HANDLE_DELEGATE_PRIORITY = 65536;
@Override public void handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) {
diff --git a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
index 4015df12..628e83dc 100644
--- a/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/javac/handlers/HandleFieldNameConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2018 The Project Lombok Authors.
+ * Copyright (C) 2014-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,6 +30,7 @@ import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
+import lombok.core.handlers.HandlerUtil;
import lombok.experimental.FieldNameConstants;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
@@ -53,7 +54,7 @@ import com.sun.tools.javac.util.Name;
@ProviderFor(JavacAnnotationHandler.class)
public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameConstants> {
- public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit) {
+ public void generateFieldNameConstantsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean asEnum, String innerTypeName, boolean onlyExplicit, boolean uppercase) {
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
@@ -74,7 +75,7 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo
if (qualified.isEmpty()) {
errorNode.addWarning("No fields qualify for @FieldNameConstants, therefore this annotation does nothing");
} else {
- createInnerTypeFieldNameConstants(typeNode, errorNode, errorNode.get(), level, qualified, asEnum, innerTypeName);
+ createInnerTypeFieldNameConstants(typeNode, errorNode, errorNode.get(), level, qualified, asEnum, innerTypeName, uppercase);
}
}
@@ -117,11 +118,13 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo
String innerTypeName = annotationInstance.innerTypeName();
if (innerTypeName.isEmpty()) innerTypeName = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_INNER_TYPE_NAME);
if (innerTypeName == null || innerTypeName.isEmpty()) innerTypeName = "Fields";
+ Boolean uppercase = annotationNode.getAst().readConfiguration(ConfigurationKeys.FIELD_NAME_CONSTANTS_UPPERCASE);
+ if (uppercase == null) uppercase = false;
- generateFieldNameConstantsForType(node, annotationNode, level, asEnum, innerTypeName, annotationInstance.onlyExplicitlyIncluded());
+ generateFieldNameConstantsForType(node, annotationNode, level, asEnum, innerTypeName, annotationInstance.onlyExplicitlyIncluded(), uppercase);
}
- private void createInnerTypeFieldNameConstants(JavacNode typeNode, JavacNode errorNode, JCTree pos, AccessLevel level, java.util.List<JavacNode> fields, boolean asEnum, String innerTypeName) {
+ private void createInnerTypeFieldNameConstants(JavacNode typeNode, JavacNode errorNode, JCTree pos, AccessLevel level, java.util.List<JavacNode> fields, boolean asEnum, String innerTypeName, boolean uppercase) {
if (fields.isEmpty()) return;
JavacTreeMaker maker = typeNode.getTreeMaker();
@@ -161,6 +164,7 @@ public class HandleFieldNameConstants extends JavacAnnotationHandler<FieldNameCo
java.util.List<JCVariableDecl> generated = new ArrayList<JCVariableDecl>();
for (JavacNode field : fields) {
Name fName = ((JCVariableDecl) field.get()).name;
+ if (uppercase) fName = typeNode.toName(HandlerUtil.camelCaseToConstant(fName.toString()));
if (fieldExists(fName.toString(), fieldsType) != MemberExistsResult.NOT_EXISTS) continue;
JCModifiers constantValueMods = maker.Modifiers(Flags.PUBLIC | Flags.STATIC | Flags.FINAL | (asEnum ? Flags.ENUM : 0L));
JCExpression returnType;
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 7eb9873b..290ef89f 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2018 The Project Lombok Authors.
+ * Copyright (C) 2013-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -725,8 +725,9 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
arg = tgt[0];
} else {
JCExpression eqNull = maker.Binary(CTC_EQUAL, tgt[0], maker.Literal(CTC_BOT, null));
- JCExpression emptyList = maker.Apply(List.<JCExpression>nil(), chainDots(type, "java", "util", "Collections", "emptyList"), List.<JCExpression>nil());
- arg = maker.Conditional(eqNull, emptyList, tgt[1]);
+ String emptyMaker = bfd.singularData.getSingularizer().getEmptyMaker(bfd.singularData.getTargetFqn());
+ JCExpression emptyCollection = maker.Apply(List.<JCExpression>nil(), chainDots(type, emptyMaker.split("\\.")), List.<JCExpression>nil());
+ arg = maker.Conditional(eqNull, emptyCollection, tgt[1]);
}
JCMethodInvocation apply = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(type.toName(BUILDER_VARIABLE_NAME)), bfd.name), List.of(arg));
JCExpressionStatement exec = maker.Exec(apply);
@@ -862,7 +863,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations);
} else {
- fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker);
+ fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
}
}
diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java
index 14130bc4..23c27bc0 100644
--- a/src/core/lombok/javac/handlers/HandleVal.java
+++ b/src/core/lombok/javac/handlers/HandleVal.java
@@ -22,6 +22,7 @@
package lombok.javac.handlers;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
+import static lombok.javac.handlers.HandleDelegate.HANDLE_DELEGATE_PRIORITY;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import lombok.ConfigurationKeys;
import lombok.val;
@@ -49,7 +50,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
@ProviderFor(JavacASTVisitor.class)
-@HandlerPriority(65536) // 2^16; resolution needs to work, so if the RHS expression is i.e. a call to a generated getter, we have to run after that getter has been generated.
+@HandlerPriority(HANDLE_DELEGATE_PRIORITY + 100) // run slightly after HandleDelegate; resolution needs to work, so if the RHS expression is i.e. a call to a generated getter, we have to run after that getter has been generated.
@ResolutionResetNeeded
public class HandleVal extends JavacASTAdapter {
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 7c707756..a5895951 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.core.LombokImmutableList;
import lombok.core.SpiLoadUtil;
@@ -157,14 +158,14 @@ public class JavacSingularsRecipes {
public static abstract class JavacSingularizer {
public abstract LombokImmutableList<String> getSupportedTypes();
-
+
protected JavacSingularizer getGuavaInstead(JavacNode node) {
return this;
}
- protected JCModifiers makeMods(JavacTreeMaker maker, JavacNode node, boolean deprecate) {
- if (deprecate) return maker.Modifiers(Flags.PUBLIC, List.<JCAnnotation>of(maker.Annotation(genJavaLangTypeRef(node, "Deprecated"), List.<JCExpression>nil())));
- return maker.Modifiers(Flags.PUBLIC);
+ protected JCModifiers makeMods(JavacTreeMaker maker, JavacNode node, boolean deprecate, AccessLevel access) {
+ if (deprecate) return maker.Modifiers(toJavacModifier(access), List.<JCAnnotation>of(maker.Annotation(genJavaLangTypeRef(node, "Deprecated"), List.<JCExpression>nil())));
+ return maker.Modifiers(toJavacModifier(access));
}
/** Checks if any of the to-be-generated nodes (fields, methods) already exist. If so, errors on these (singulars don't support manually writing some of it, and returns true). */
@@ -219,7 +220,7 @@ public class JavacSingularsRecipes {
* If you need more control over the return type and value, use
* {@link #generateMethods(SingularData, boolean, JavacNode, JCTree, boolean, ExpressionMaker, StatementMaker)}.
*/
- public void generateMethods(SingularData data, boolean deprecate, final JavacNode builderType, JCTree source, boolean fluent, final boolean chain) {
+ public void generateMethods(SingularData data, boolean deprecate, final JavacNode builderType, JCTree source, boolean fluent, final boolean chain, AccessLevel access) {
final JavacTreeMaker maker = builderType.getTreeMaker();
ExpressionMaker returnTypeMaker = new ExpressionMaker() { @Override public JCExpression make() {
@@ -232,54 +233,54 @@ public class JavacSingularsRecipes {
return chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
}};
- generateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
+ generateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker, access);
}
/**
* Generates the singular, plural, and clear methods for the given {@link SingularData}.
* Uses the given {@code returnTypeMaker} and {@code returnStatementMaker} for the generated methods.
*/
- public abstract void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker);
-
- protected void doGenerateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
+ public abstract void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access);
+
+ protected void doGenerateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
JavacTreeMaker maker = builderType.getTreeMaker();
- generateSingularMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
- generatePluralMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent);
- generateClearMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source);
+ generateSingularMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent, access);
+ generatePluralMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, fluent, access);
+ generateClearMethod(deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, access);
}
-
- private void finishAndInjectMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer<JCStatement> statements, Name methodName, List<JCVariableDecl> jcVariableDecls) {
+
+ private void finishAndInjectMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer<JCStatement> statements, Name methodName, List<JCVariableDecl> jcVariableDecls, AccessLevel access) {
if (returnStatement != null) statements.append(returnStatement);
JCBlock body = maker.Block(0, statements.toList());
- JCModifiers mods = makeMods(maker, builderType, deprecate);
+ JCModifiers mods = makeMods(maker, builderType, deprecate, access);
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrown = List.nil();
JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, jcVariableDecls, thrown, body, null);
recursiveSetGeneratedBy(method, source, builderType.getContext());
injectMethod(builderType, method);
}
-
- private void generateClearMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source) {
+
+ private void generateClearMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, AccessLevel access) {
JCStatement clearStatement = generateClearStatements(maker, data, builderType);
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
statements.add(clearStatement);
-
+
Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString()));
- finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.<JCVariableDecl>nil());
+ finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.<JCVariableDecl>nil(), access);
}
-
+
protected abstract JCStatement generateClearStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType);
-
- private void generateSingularMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
+
+ private void generateSingularMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent, AccessLevel access) {
ListBuffer<JCStatement> statements = generateSingularMethodStatements(maker, data, builderType, source);
List<JCVariableDecl> params = generateSingularMethodParameters(maker, data, builderType, source);
Name name = data.getSingularName();
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName(), name.toString()));
-
+
statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
- finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params);
+ finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, access);
}
-
+
protected JCVariableDecl generateSingularMethodParameter(int typeIndex, JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source, Name name) {
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
JCExpression type = cloneParamType(typeIndex, maker, data.getTypeArgs(), builderType, source);
@@ -288,18 +289,18 @@ public class JavacSingularsRecipes {
JCModifiers mods = typeUseAnns.isEmpty() ? maker.Modifiers(flags) : maker.Modifiers(flags, typeUseAnns);
return maker.VarDef(mods, name, type, null);
}
-
+
protected JCStatement generateSingularMethodAddStatement(JavacTreeMaker maker, JavacNode builderType, Name argumentName, String builderFieldName) {
JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", builderFieldName, "add");
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, List.<JCExpression>of(maker.Ident(argumentName)));
return maker.Exec(invokeAdd);
}
-
+
protected abstract ListBuffer<JCStatement> generateSingularMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source);
-
+
protected abstract List<JCVariableDecl> generateSingularMethodParameters(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source);
-
- private void generatePluralMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
+
+ private void generatePluralMethod(boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent, AccessLevel access) {
ListBuffer<JCStatement> statements = generatePluralMethodStatements(maker, data, builderType, source);
Name name = data.getPluralName();
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName() + "All", name.toString()));
@@ -308,19 +309,19 @@ public class JavacSingularsRecipes {
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
- finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param));
+ finishAndInjectMethod(maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), access);
}
-
+
protected ListBuffer<JCStatement> generatePluralMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName() + "All");
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, List.<JCExpression>of(maker.Ident(data.getPluralName())));
return new ListBuffer<JCStatement>().append(maker.Exec(invokeAdd));
}
-
+
protected abstract JCExpression getPluralMethodParamType(JavacNode builderType);
-
+
protected abstract JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source);
-
+
public abstract void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable);
public boolean requiresCleaning() {
@@ -432,9 +433,11 @@ public class JavacSingularsRecipes {
}
}
}
-
+
protected abstract String getAddMethodName();
-
+
protected abstract int getTypeArgumentsCount();
+
+ protected abstract String getEmptyMaker(String target);
}
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index 17be15dc..5b022206 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -26,6 +26,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.Collections;
+import lombok.AccessLevel;
import lombok.core.GuavaTypeMap;
import lombok.core.LombokImmutableList;
import lombok.javac.JavacNode;
@@ -50,6 +51,10 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
return GuavaTypeMap.getGuavaTypeName(data.getTargetFqn());
}
+ @Override protected String getEmptyMaker(String target) {
+ return target + ".of";
+ }
+
protected String getBuilderMethodName(SingularData data) {
String simpleTypeName = getSimpleTargetTypeName(data);
if ("ImmutableSortedSet".equals(simpleTypeName) || "ImmutableSortedMap".equals(simpleTypeName)) return "naturalOrder";
@@ -66,8 +71,8 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
- doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
+ @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker, access);
}
@Override
@@ -75,7 +80,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
return maker.Exec(maker.Assign(thisDotField, maker.Literal(CTC_BOT, null)));
}
-
+
@Override
protected List<JCVariableDecl> generateSingularMethodParameters(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
Name[] names = generateSingularMethodParameterNames(data, builderType);
@@ -85,11 +90,11 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
}
return params.toList();
}
-
+
@Override
protected ListBuffer<JCStatement> generateSingularMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
Name[] names = generateSingularMethodParameterNames(data, builderType);
-
+
JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName());
ListBuffer<JCExpression> invokeAddExprBuilder = new ListBuffer<JCExpression>();
for (Name name : names) {
@@ -98,10 +103,10 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
List<JCExpression> invokeAddExpr = invokeAddExprBuilder.toList();
JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, invokeAddExpr);
JCStatement st = maker.Exec(invokeAdd);
-
+
return new ListBuffer<JCStatement>().append(st);
}
-
+
private Name[] generateSingularMethodParameterNames(SingularData data, JavacNode builderType) {
LombokImmutableList<String> suffixes = getArgumentSuffixes();
Name[] names = new Name[suffixes.size()];
@@ -112,7 +117,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
}
return names;
}
-
+
@Override
protected JCExpression getPluralMethodParamType(JavacNode builderType) {
JCExpression paramType;
@@ -124,7 +129,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
}
return paramType;
}
-
+
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable) {
JavacTreeMaker maker = builderType.getTreeMaker();
List<JCExpression> jceBlank = List.nil();
@@ -171,9 +176,9 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
}
protected abstract LombokImmutableList<String> getArgumentSuffixes();
-
+
protected abstract String getAddAllTypeName();
-
+
@Override
protected int getTypeArgumentsCount() {
return getArgumentSuffixes().size();
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
index bbe6eb63..9d24f5d5 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.Collections;
+import lombok.AccessLevel;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.javac.handlers.JavacHandlerUtil;
@@ -44,11 +45,10 @@ import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularizer {
-
@Override protected JavacSingularizer getGuavaInstead(JavacNode node) {
return new JavacGuavaSetListSingularizer();
}
-
+
@Override public java.util.List<Name> listFieldsToBeGenerated(SingularData data, JavacNode builderType) {
return super.listFieldsToBeGenerated(data, builderType);
}
@@ -66,49 +66,49 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
- doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
+ @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker, access);
}
-
+
@Override
protected JCStatement generateClearStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType) {
List<JCExpression> jceBlank = List.nil();
JCExpression thisDotField = maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName());
JCExpression thisDotFieldDotClear = maker.Select(maker.Select(maker.Ident(builderType.toName("this")), data.getPluralName()), builderType.toName("clear"));
-
+
JCStatement clearCall = maker.Exec(maker.Apply(jceBlank, thisDotFieldDotClear, jceBlank));
JCExpression cond = maker.Binary(CTC_NOT_EQUAL, thisDotField, maker.Literal(CTC_BOT, null));
-
+
return maker.If(cond, clearCall, null);
}
-
+
@Override
protected ListBuffer<JCStatement> generateSingularMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
return new ListBuffer<JCStatement>()
.append(generateSingularMethodAddStatement(maker, builderType, data.getSingularName(), data.getPluralName().toString()));
}
-
+
@Override
protected List<JCVariableDecl> generateSingularMethodParameters(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
JCVariableDecl param = generateSingularMethodParameter(0, maker, data, builderType, source, data.getSingularName());
return List.of(param);
}
-
+
@Override
protected JCExpression getPluralMethodParamType(JavacNode builderType) {
return chainDots(builderType, "java", "util", "Collection");
}
-
+
@Override
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
return createConstructBuilderVarIfNeeded(maker, data, builderType, false, source);
}
-
+
@Override
protected String getAddMethodName() {
return "add";
}
-
+
@Override
protected int getTypeArgumentsCount() {
return 1;
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
index e5c5a170..b4ad3428 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
@@ -46,6 +46,10 @@ public class JavacJavaUtilListSingularizer extends JavacJavaUtilListSetSingulari
return LombokImmutableList.of("java.util.List", "java.util.Collection", "java.lang.Iterable");
}
+ @Override protected String getEmptyMaker(String target) {
+ return "java.util.Collections.emptyList";
+ }
+
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable) {
JavacTreeMaker maker = builderType.getTreeMaker();
List<JCExpression> jceBlank = List.nil();
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
index 71ddd01d..3e498cac 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2018 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.Arrays;
+import lombok.AccessLevel;
import lombok.core.LombokImmutableList;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
@@ -49,15 +50,20 @@ import com.sun.tools.javac.util.Name;
@ProviderFor(JavacSingularizer.class)
public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
-
@Override public LombokImmutableList<String> getSupportedTypes() {
return LombokImmutableList.of("java.util.Map", "java.util.SortedMap", "java.util.NavigableMap");
}
-
+
+ @Override protected String getEmptyMaker(String target) {
+ if (target.endsWith("NavigableMap")) return "java.util.Collections.emptyNavigableMap";
+ if (target.endsWith("SortedMap")) return "java.util.Collections.emptySortedMap";
+ return "java.util.Collections.emptyMap";
+ }
+
@Override protected JavacSingularizer getGuavaInstead(JavacNode node) {
return new JavacGuavaMapSingularizer();
}
-
+
@Override public java.util.List<Name> listFieldsToBeGenerated(SingularData data, JavacNode builderType) {
String p = data.getPluralName().toString();
return Arrays.asList(builderType.toName(p + "$key"), builderType.toName(p + "$value"));
@@ -91,10 +97,10 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
return Arrays.asList(keyFieldNode, valueFieldNode);
}
- @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker) {
- doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker);
+ @Override public void generateMethods(SingularData data, boolean deprecate, JavacNode builderType, JCTree source, boolean fluent, ExpressionMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ doGenerateMethods(data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker, access);
}
-
+
@Override
protected JCStatement generateClearStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType) {
List<JCExpression> jceBlank = List.nil();
@@ -108,12 +114,12 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
JCBlock clearCalls = maker.Block(0, List.of(clearKeyCall, clearValueCall));
return maker.If(cond, clearCalls, null);
}
-
+
@Override
protected ListBuffer<JCStatement> generateSingularMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
Name keyName = builderType.toName(data.getSingularName().toString() + "Key");
Name valueName = builderType.toName(data.getSingularName().toString() + "Value");
-
+
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
/* Generates: this.pluralname$key.add(singularnameKey); */
statements.append(generateSingularMethodAddStatement(maker, builderType, keyName, data.getPluralName() + "$key"));
@@ -121,7 +127,7 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
statements.append(generateSingularMethodAddStatement(maker, builderType, valueName, data.getPluralName() + "$value"));
return statements;
}
-
+
@Override
protected List<JCVariableDecl> generateSingularMethodParameters(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
Name keyName = builderType.toName(data.getSingularName().toString() + "Key");
@@ -130,7 +136,7 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
JCVariableDecl paramValue = generateSingularMethodParameter(1, maker, data, builderType, source, valueName);
return List.of(paramKey, paramValue);
}
-
+
@Override
protected ListBuffer<JCStatement> generatePluralMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
List<JCExpression> jceBlank = List.nil();
@@ -150,17 +156,17 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
statements.append(forEach);
return statements;
}
-
+
@Override
protected JCExpression getPluralMethodParamType(JavacNode builderType) {
return chainDots(builderType, "java", "util", "Map");
}
-
+
@Override
protected JCStatement createConstructBuilderVarIfNeeded(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) {
return createConstructBuilderVarIfNeeded(maker, data, builderType, true, source);
}
-
+
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable) {
JavacTreeMaker maker = builderType.getTreeMaker();
@@ -170,12 +176,12 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer {
statements.appendList(createJavaUtilSimpleCreationAndFillStatements(maker, data, builderType, true, true, false, true, "TreeMap", source, builderVariable));
}
}
-
+
@Override
protected String getAddMethodName() {
return "put";
}
-
+
@Override
protected int getTypeArgumentsCount() {
return 2;
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSetSingularizer.java
index 22d74896..7c870c0a 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSetSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSetSingularizer.java
@@ -40,6 +40,12 @@ public class JavacJavaUtilSetSingularizer extends JavacJavaUtilListSetSingulariz
return LombokImmutableList.of("java.util.Set", "java.util.SortedSet", "java.util.NavigableSet");
}
+ @Override protected String getEmptyMaker(String target) {
+ if (target.endsWith("SortedSet")) return "java.util.Collections.emptySortedSet";
+ if (target.endsWith("NavigableSet")) return "java.util.Collections.emptyNavigableSet";
+ return "java.util.Collections.emptySet";
+ }
+
@Override public void appendBuildCode(SingularData data, JavacNode builderType, JCTree source, ListBuffer<JCStatement> statements, Name targetVariableName, String builderVariable) {
JavacTreeMaker maker = builderType.getTreeMaker();
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
index 8c22a41e..50950915 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Project Lombok Authors.
+ * Copyright (C) 2015-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,14 +32,12 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
-import lombok.ConfigurationKeys;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
abstract class JavacJavaUtilSingularizer extends JavacSingularizer {
-
protected List<JCStatement> createJavaUtilSetMapInitialCapacitySwitchStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, boolean mapMode, String emptyCollectionMethod, String singletonCollectionMethod, String targetType, JCTree source, String builderVariable) {
List<JCExpression> jceBlank = List.nil();
ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 8f4f99e5..76b2715a 100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -93,6 +93,7 @@ public class Delombok {
private boolean noCopy;
private boolean onlyChanged;
private boolean force = false;
+ private boolean disablePreview;
private String classpath, sourcepath, bootclasspath, modulepath;
private LinkedHashMap<File, File> fileToBase = new LinkedHashMap<File, File>();
private List<File> filesToParse = new ArrayList<File>();
@@ -158,6 +159,10 @@ public class Delombok {
@Description("Output only changed files (implies -n)")
private boolean onlyChanged;
+ @Description("By default lombok enables preview features if available (introduced in JDK 12). With this option, lombok won't do that.")
+ @FullName("disable-preview")
+ private boolean disablePreview;
+
private boolean help;
}
@@ -281,6 +286,7 @@ public class Delombok {
if (args.verbose) delombok.setVerbose(true);
if (args.nocopy || args.onlyChanged) delombok.setNoCopy(true);
+ if (args.disablePreview) delombok.setDisablePreview(true);
if (args.onlyChanged) delombok.setOnlyChanged(true);
if (args.print) {
delombok.setOutputToStandardOut();
@@ -516,6 +522,10 @@ public class Delombok {
this.noCopy = noCopy;
}
+ public void setDisablePreview(boolean disablePreview) {
+ this.disablePreview = disablePreview;
+ }
+
public void setOnlyChanged(boolean onlyChanged) {
this.onlyChanged = onlyChanged;
}
@@ -684,6 +694,9 @@ public class Delombok {
argsList.add("--module-path");
argsList.add(modulepath);
}
+
+ if (!disablePreview && Javac.getJavaCompilerVersion() >= 11) argsList.add("--enable-preview");
+
String[] argv = argsList.toArray(new String[0]);
args.init("javac", argv);
options.put("diags.legacy", "TRUE");
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 832dbe0a..3477c51c 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -1046,9 +1046,17 @@ public class PrettyPrinter extends JCTree.Visitor {
@Override public void visitBreak(JCBreak tree) {
aPrint("break");
- if (tree.label != null) {
+
+ JCExpression value = readObject(tree, "value", null); // JDK 12+
+ if (value != null) {
print(" ");
- print(tree.label);
+ print(value);
+ } else {
+ Name label = readObject(tree, "label", null);
+ if (label != null) {
+ print(" ");
+ print(label);
+ }
}
println(";", tree);
}
@@ -1230,16 +1238,41 @@ public class PrettyPrinter extends JCTree.Visitor {
}
@Override public void visitCase(JCCase tree) {
- if (tree.pat == null) {
+ // Starting with JDK12, switches allow multiple expressions per case, and can take the form of an expression (preview feature).
+
+ List<JCExpression> pats = readObject(tree, "pats", null); // JDK 12+
+ if (pats == null) {
+ JCExpression pat = readObject(tree, "pat", null); // JDK -11
+ pats = pat == null ? List.<JCExpression>nil() : List.of(pat);
+ }
+
+ if (pats.isEmpty()) {
aPrint("default");
} else {
aPrint("case ");
- print(tree.pat);
+ print(pats, ", ");
+ }
+
+ Enum<?> caseKind = readObject(tree, "caseKind", null); // JDK 12+
+
+ if (caseKind != null && caseKind.name().equalsIgnoreCase("RULE")) {
+ print(" -> ");
+ if (tree.stats.head instanceof JCBreak) {
+ JCBreak b = (JCBreak) tree.stats.head;
+ print((JCExpression) readObject(b, "value", null));
+ print(";");
+ needsNewLine = true;
+ needsAlign = true;
+ } else {
+ print(tree.stats.head);
+ if (tree.stats.head instanceof JCBlock) needsNewLine = false;
+ }
+ } else {
+ println(": ");
+ indent++;
+ print(tree.stats, "");
+ indent--;
}
- println(": ");
- indent++;
- print(tree.stats, "");
- indent--;
}
@Override public void visitCatch(JCCatch tree) {
@@ -1259,10 +1292,26 @@ public class PrettyPrinter extends JCTree.Visitor {
print(")");
}
println(" {");
- print(tree.cases, "\n");
+ print(tree.cases, "");
aPrintln("}", tree);
}
+ void printSwitchExpression(JCTree tree) {
+ aPrint("switch ");
+ JCExpression selector = readObject(tree, "selector", null);
+ if (selector instanceof JCParens) {
+ print(selector);
+ } else {
+ print("(");
+ print(selector);
+ print(")");
+ }
+ println(" {");
+ List<JCCase> cases = readObject(tree, "cases", null);
+ print(cases, "");
+ aPrint("}");
+ }
+
@Override public void visitTry(JCTry tree) {
aPrint("try ");
List<?> resources = readObject(tree, "resources", List.nil());
@@ -1481,6 +1530,8 @@ public class PrettyPrinter extends JCTree.Visitor {
printAnnotatedType0(tree);
} else if ("JCPackageDecl".equals(simpleName)) {
// Starting with JDK9, this is inside the import list, but we've already printed it. Just ignore it.
+ } else if ("JCSwitchExpression".equals(simpleName)) { // Introduced as preview feature in JDK12
+ printSwitchExpression(tree);
} else {
throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree);
}
diff --git a/src/delombok/lombok/delombok/ant/DelombokTask.java b/src/delombok/lombok/delombok/ant/DelombokTask.java
index e09b8ed2..cb31ef4d 100644
--- a/src/delombok/lombok/delombok/ant/DelombokTask.java
+++ b/src/delombok/lombok/delombok/ant/DelombokTask.java
@@ -154,10 +154,6 @@ class Tasks {
path.add(set);
}
- public Format createFormat() {
- return new Format();
- }
-
public void addFormat(Format format) {
formatOptions.add(format);
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
index 12f4ad3d..b32c99cd 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java
@@ -263,11 +263,15 @@ public class PatchVal {
resolved = null;
}
if (resolved != null) {
- try {
- replacement = makeType(resolved, local.type, false);
- if (!decomponent) init.resolvedType = replacement.resolveType(scope);
- } catch (Exception e) {
- // Some type thing failed.
+ 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.
+ }
}
}
}
diff --git a/src/installer/lombok/installer/OsUtils.java b/src/installer/lombok/installer/OsUtils.java
index 2da7de09..022ff2e5 100644
--- a/src/installer/lombok/installer/OsUtils.java
+++ b/src/installer/lombok/installer/OsUtils.java
@@ -53,14 +53,14 @@ public final class OsUtils {
dll1.deleteOnExit();
dll2.deleteOnExit();
try {
- if (unpackDLL("WindowsDriveInfo-i386.dll", dll1)) {
+ if (unpackDLL("WindowsDriveInfo-i386.binary", dll1)) {
System.load(dll1.getAbsolutePath());
return;
}
} catch (Throwable ignore) {}
try {
- if (unpackDLL("WindowsDriveInfo-x86_64.dll", dll2)) {
+ if (unpackDLL("WindowsDriveInfo-x86_64.binary", dll2)) {
System.load(dll2.getAbsolutePath());
}
} catch (Throwable ignore) {}
diff --git a/src/installer/lombok/installer/WindowsDriveInfo-i386.dll b/src/installer/lombok/installer/WindowsDriveInfo-i386.binary
index eb7fa49a..eb7fa49a 100644
--- a/src/installer/lombok/installer/WindowsDriveInfo-i386.dll
+++ b/src/installer/lombok/installer/WindowsDriveInfo-i386.binary
Binary files differ
diff --git a/src/installer/lombok/installer/WindowsDriveInfo-x86_64.dll b/src/installer/lombok/installer/WindowsDriveInfo-x86_64.binary
index 0b7c9a83..0b7c9a83 100644
--- a/src/installer/lombok/installer/WindowsDriveInfo-x86_64.dll
+++ b/src/installer/lombok/installer/WindowsDriveInfo-x86_64.binary
Binary files differ
diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java
index 83d9c53f..84293f11 100644
--- a/src/utils/lombok/javac/JavacTreeMaker.java
+++ b/src/utils/lombok/javac/JavacTreeMaker.java
@@ -441,7 +441,11 @@ public class JavacTreeMaker {
//javac versions: 6-8
private static final MethodId<JCVariableDecl> VarDef = MethodId("VarDef");
public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
- return invoke(VarDef, mods, name, vartype, init);
+ JCVariableDecl varDef = invoke(VarDef, mods, name, vartype, init);
+ // We use 'position of the type is -1' as indicator in delombok that the original node was written using JDK10's 'var' feature, because javac desugars 'var' to the real type and doesn't leave any markers other than the
+ // node position to indicate that it did so. Unfortunately, that means vardecls we generate look like 'var' to delombok. Adjust the position to avoid this.
+ if (varDef.vartype != null && varDef.vartype.pos == -1) varDef.vartype.pos = 0;
+ return varDef;
}
//javac versions: 8
diff --git a/src/utils/lombok/permit/Permit.java b/src/utils/lombok/permit/Permit.java
index 9f0434b8..b7c5f0d9 100644
--- a/src/utils/lombok/permit/Permit.java
+++ b/src/utils/lombok/permit/Permit.java
@@ -46,8 +46,7 @@ public class Permit {
Throwable ex;
try {
- f = AccessibleObject.class.getDeclaredField("override");
- g = UNSAFE.objectFieldOffset(f);
+ g = getOverrideFieldOffset();
ex = null;
} catch (Throwable t) {
f = null;
@@ -74,6 +73,30 @@ public class Permit {
return accessor;
}
+ private static long getOverrideFieldOffset() throws Throwable {
+ Field f = null;
+ Throwable saved = null;
+ try {
+ f = AccessibleObject.class.getDeclaredField("override");
+ } catch (Throwable t) {
+ saved = t;
+ }
+
+ if (f != null) {
+ return UNSAFE.objectFieldOffset(f);
+ }
+ // The below seems very risky, but for all AccessibleObjects in java today it does work, and starting with JDK12, making the field accessible is no longer possible.
+ try {
+ return UNSAFE.objectFieldOffset(Fake.class.getDeclaredField("override"));
+ } catch (Throwable t) {
+ throw saved;
+ }
+ }
+
+ static class Fake {
+ boolean override;
+ }
+
public static Method getMethod(Class<?> c, String mName, Class<?>... parameterTypes) throws NoSuchMethodException {
Method m = null;
Class<?> oc = c;
diff --git a/test/core/src/lombok/DirectoryRunner.java b/test/core/src/lombok/DirectoryRunner.java
index ea15cdb9..9410b4c7 100644
--- a/test/core/src/lombok/DirectoryRunner.java
+++ b/test/core/src/lombok/DirectoryRunner.java
@@ -91,7 +91,7 @@ public class DirectoryRunner extends Runner {
public DirectoryRunner(Class<?> testClass) throws Exception {
description = Description.createSuiteDescription(testClass);
- this.params = (TestParams) testClass.newInstance();
+ this.params = (TestParams) testClass.getConstructor().newInstance();
Throwable error = null;
try {
diff --git a/test/pretty/resource/after/Java11Var.javva b/test/pretty/resource/after/Java11Var.java
index cec4be6d..cec4be6d 100644
--- a/test/pretty/resource/after/Java11Var.javva
+++ b/test/pretty/resource/after/Java11Var.java
diff --git a/test/pretty/resource/after/Switch11.java b/test/pretty/resource/after/Switch11.java
new file mode 100644
index 00000000..d24012a2
--- /dev/null
+++ b/test/pretty/resource/after/Switch11.java
@@ -0,0 +1,11 @@
+public class Switch11 {
+ public void basic() {
+ switch (5) {
+ case 1:
+ case 2:
+ System.out.println("OK");
+ break;
+ default:
+ }
+ }
+}
diff --git a/test/pretty/resource/after/Switch12.java b/test/pretty/resource/after/Switch12.java
new file mode 100644
index 00000000..89825223
--- /dev/null
+++ b/test/pretty/resource/after/Switch12.java
@@ -0,0 +1,28 @@
+public class Switch12 {
+ public void basic() {
+ switch (5) {
+ case 1:
+ case 2:
+ System.out.println("OK");
+ break;
+ default:
+ }
+ }
+ public void multiCase() {
+ switch (5) {
+ case 1, 2:
+ System.out.println("OK");
+ default:
+ }
+ }
+
+ public int switchExpr() {
+ return switch (5) {
+ case 1, 2 -> 0;
+ case 3 -> {
+ break 10;
+ }
+ default -> 10;
+ } + 10;
+ }
+}
diff --git a/test/pretty/resource/before/Switch11.java b/test/pretty/resource/before/Switch11.java
new file mode 100644
index 00000000..556631f0
--- /dev/null
+++ b/test/pretty/resource/before/Switch11.java
@@ -0,0 +1,12 @@
+// version :11
+public class Switch11 {
+ public void basic() {
+ switch (5) {
+ case 1:
+ case 2:
+ System.out.println("OK");
+ break;
+ default:
+ }
+ }
+}
diff --git a/test/pretty/resource/before/Switch12.java b/test/pretty/resource/before/Switch12.java
new file mode 100644
index 00000000..f1bd8a79
--- /dev/null
+++ b/test/pretty/resource/before/Switch12.java
@@ -0,0 +1,30 @@
+// version 12:
+public class Switch12 {
+ public void basic() {
+ switch (5) {
+ case 1:
+ case 2:
+ System.out.println("OK");
+ break;
+ default:
+ }
+ }
+
+ public void multiCase() {
+ switch (5) {
+ case 1, 2:
+ System.out.println("OK");
+ default:
+ }
+ }
+
+ public int switchExpr() {
+ return switch (5) {
+ case 1, 2 -> 0;
+ case 3 -> {
+ break 10;
+ }
+ default -> 10;
+ } + 10;
+ }
+}
diff --git a/test/transform/resource/after-delombok/BuilderSimple.java b/test/transform/resource/after-delombok/BuilderSimple.java
index e3821c9a..4cd20b23 100644
--- a/test/transform/resource/after-delombok/BuilderSimple.java
+++ b/test/transform/resource/after-delombok/BuilderSimple.java
@@ -10,7 +10,7 @@ class BuilderSimple<T> {
this.also = also;
}
@java.lang.SuppressWarnings("all")
- public static class BuilderSimpleBuilder<T> {
+ protected static class BuilderSimpleBuilder<T> {
@java.lang.SuppressWarnings("all")
private int yes;
@java.lang.SuppressWarnings("all")
@@ -39,7 +39,7 @@ class BuilderSimple<T> {
}
}
@java.lang.SuppressWarnings("all")
- public static <T> BuilderSimpleBuilder<T> builder() {
+ protected static <T> BuilderSimpleBuilder<T> builder() {
return new BuilderSimpleBuilder<T>();
}
}
diff --git a/test/transform/resource/after-delombok/FieldNameConstantsUppercased.java b/test/transform/resource/after-delombok/FieldNameConstantsUppercased.java
new file mode 100644
index 00000000..dd7de86a
--- /dev/null
+++ b/test/transform/resource/after-delombok/FieldNameConstantsUppercased.java
@@ -0,0 +1,12 @@
+public class FieldNameConstantsUppercased {
+ String iAmADvdPlayer;
+ int $skipMe;
+ static double skipMeToo;
+ int andMe;
+ String butPrintMePlease;
+ @java.lang.SuppressWarnings("all")
+ static final class Fields {
+ public static final java.lang.String I_AM_A_DVD_PLAYER = "iAmADvdPlayer";
+ public static final java.lang.String BUT_PRINT_ME_PLEASE = "butPrintMePlease";
+ }
+}
diff --git a/test/transform/resource/after-delombok/SuperBuilderWithGenericsAndToBuilder.java b/test/transform/resource/after-delombok/SuperBuilderWithGenericsAndToBuilder.java
index deb5a223..af67e900 100644
--- a/test/transform/resource/after-delombok/SuperBuilderWithGenericsAndToBuilder.java
+++ b/test/transform/resource/after-delombok/SuperBuilderWithGenericsAndToBuilder.java
@@ -1,14 +1,16 @@
-import java.util.List;
+import java.util.Map;
public class SuperBuilderWithGenericsAndToBuilder {
public static class Parent<A> {
A field1;
- List<String> items;
+ Map<Integer, String> items;
@java.lang.SuppressWarnings("all")
public static abstract class ParentBuilder<A, C extends Parent<A>, B extends ParentBuilder<A, C, B>> {
@java.lang.SuppressWarnings("all")
private A field1;
@java.lang.SuppressWarnings("all")
- private java.util.ArrayList<String> items;
+ private java.util.ArrayList<Integer> items$key;
+ @java.lang.SuppressWarnings("all")
+ private java.util.ArrayList<String> items$value;
@java.lang.SuppressWarnings("all")
protected B $fillValuesFrom(final C instance) {
ParentBuilder.$fillValuesFromInstanceIntoBuilder(instance, this);
@@ -17,7 +19,7 @@ public class SuperBuilderWithGenericsAndToBuilder {
@java.lang.SuppressWarnings("all")
private static <A> void $fillValuesFromInstanceIntoBuilder(final Parent<A> instance, final ParentBuilder<A, ?, ?> b) {
b.field1(instance.field1);
- b.items(instance.items == null ? java.util.Collections.emptyList() : instance.items);
+ b.items(instance.items == null ? java.util.Collections.emptyMap() : instance.items);
}
@java.lang.SuppressWarnings("all")
protected abstract B self();
@@ -29,26 +31,39 @@ public class SuperBuilderWithGenericsAndToBuilder {
return self();
}
@java.lang.SuppressWarnings("all")
- public B item(final String item) {
- if (this.items == null) this.items = new java.util.ArrayList<String>();
- this.items.add(item);
+ public B item(final Integer itemKey, final String itemValue) {
+ if (this.items$key == null) {
+ this.items$key = new java.util.ArrayList<Integer>();
+ this.items$value = new java.util.ArrayList<String>();
+ }
+ this.items$key.add(itemKey);
+ this.items$value.add(itemValue);
return self();
}
@java.lang.SuppressWarnings("all")
- public B items(final java.util.Collection<? extends String> items) {
- if (this.items == null) this.items = new java.util.ArrayList<String>();
- this.items.addAll(items);
+ public B items(final java.util.Map<? extends Integer, ? extends String> items) {
+ if (this.items$key == null) {
+ this.items$key = new java.util.ArrayList<Integer>();
+ this.items$value = new java.util.ArrayList<String>();
+ }
+ for (final java.util.Map.Entry<? extends Integer, ? extends String> $lombokEntry : items.entrySet()) {
+ this.items$key.add($lombokEntry.getKey());
+ this.items$value.add($lombokEntry.getValue());
+ }
return self();
}
@java.lang.SuppressWarnings("all")
public B clearItems() {
- if (this.items != null) this.items.clear();
+ if (this.items$key != null) {
+ this.items$key.clear();
+ this.items$value.clear();
+ }
return self();
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
- return "SuperBuilderWithGenericsAndToBuilder.Parent.ParentBuilder(field1=" + this.field1 + ", items=" + this.items + ")";
+ return "SuperBuilderWithGenericsAndToBuilder.Parent.ParentBuilder(field1=" + this.field1 + ", items$key=" + this.items$key + ", items$value=" + this.items$value + ")";
}
}
@java.lang.SuppressWarnings("all")
@@ -70,16 +85,18 @@ public class SuperBuilderWithGenericsAndToBuilder {
@java.lang.SuppressWarnings("all")
protected Parent(final ParentBuilder<A, ?, ?> b) {
this.field1 = b.field1;
- java.util.List<String> items;
- switch (b.items == null ? 0 : b.items.size()) {
+ java.util.Map<Integer, String> items;
+ switch (b.items$key == null ? 0 : b.items$key.size()) {
case 0:
- items = java.util.Collections.emptyList();
+ items = java.util.Collections.emptyMap();
break;
case 1:
- items = java.util.Collections.singletonList(b.items.get(0));
+ items = java.util.Collections.singletonMap(b.items$key.get(0), b.items$value.get(0));
break;
default:
- items = java.util.Collections.unmodifiableList(new java.util.ArrayList<String>(b.items));
+ items = new java.util.LinkedHashMap<Integer, String>(b.items$key.size() < 1073741824 ? 1 + b.items$key.size() + (b.items$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE);
+ for (int $i = 0; $i < b.items$key.size(); $i++) items.put(b.items$key.get($i), (String) b.items$value.get($i));
+ items = java.util.Collections.unmodifiableMap(items);
}
this.items = items;
}
@@ -157,6 +174,6 @@ public class SuperBuilderWithGenericsAndToBuilder {
}
}
public static void test() {
- Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item("").build().toBuilder().build();
+ Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item(5, "").build().toBuilder().build();
}
}
diff --git a/test/transform/resource/after-delombok/ValDelegateMethodReference.java b/test/transform/resource/after-delombok/ValDelegateMethodReference.java
new file mode 100644
index 00000000..186e2aaa
--- /dev/null
+++ b/test/transform/resource/after-delombok/ValDelegateMethodReference.java
@@ -0,0 +1,65 @@
+import java.util.function.Function;
+
+public class ValDelegateMethodReference {
+ public void config() {
+ final Column<Entity, java.lang.String> column = createColumn(Entity::getValue);
+ }
+
+ private <V> Column<Entity, V> createColumn(Function<Entity, V> func) {
+ return new Column<>(func);
+ }
+}
+
+class Column<T, V> {
+ public Column(Function<T, V> vp) {
+ }
+}
+
+class Entity {
+ private MyDelegate innerDelegate;
+
+ @java.lang.SuppressWarnings("all")
+ public java.lang.String getValue() {
+ return this.innerDelegate.getValue();
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public java.lang.Boolean getABoolean() {
+ return this.innerDelegate.getABoolean();
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public void setValue(final java.lang.String value) {
+ this.innerDelegate.setValue(value);
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public void setABoolean(final java.lang.Boolean aBoolean) {
+ this.innerDelegate.setABoolean(aBoolean);
+ }
+}
+
+class MyDelegate {
+ private String value;
+ private Boolean aBoolean;
+
+ @java.lang.SuppressWarnings("all")
+ public String getValue() {
+ return this.value;
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public Boolean getABoolean() {
+ return this.aBoolean;
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ @java.lang.SuppressWarnings("all")
+ public void setABoolean(final Boolean aBoolean) {
+ this.aBoolean = aBoolean;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/BuilderSimple.java b/test/transform/resource/after-ecj/BuilderSimple.java
index bc0ff186..9d9fb7f3 100644
--- a/test/transform/resource/after-ecj/BuilderSimple.java
+++ b/test/transform/resource/after-ecj/BuilderSimple.java
@@ -1,6 +1,6 @@
import java.util.List;
-@lombok.Builder class BuilderSimple<T> {
- public static @java.lang.SuppressWarnings("all") class BuilderSimpleBuilder<T> {
+@lombok.Builder(access = lombok.AccessLevel.PROTECTED) class BuilderSimple<T> {
+ protected static @java.lang.SuppressWarnings("all") class BuilderSimpleBuilder<T> {
private @java.lang.SuppressWarnings("all") int yes;
private @java.lang.SuppressWarnings("all") List<T> also;
@java.lang.SuppressWarnings("all") BuilderSimpleBuilder() {
@@ -30,7 +30,7 @@ import java.util.List;
this.yes = yes;
this.also = also;
}
- public static @java.lang.SuppressWarnings("all") <T>BuilderSimpleBuilder<T> builder() {
+ protected static @java.lang.SuppressWarnings("all") <T>BuilderSimpleBuilder<T> builder() {
return new BuilderSimpleBuilder<T>();
}
}
diff --git a/test/transform/resource/after-ecj/FieldNameConstantsUppercased.java b/test/transform/resource/after-ecj/FieldNameConstantsUppercased.java
new file mode 100644
index 00000000..a858b91f
--- /dev/null
+++ b/test/transform/resource/after-ecj/FieldNameConstantsUppercased.java
@@ -0,0 +1,23 @@
+import lombok.experimental.FieldNameConstants;
+import lombok.AccessLevel;
+public @FieldNameConstants(level = AccessLevel.PACKAGE) class FieldNameConstantsUppercased {
+ static final @java.lang.SuppressWarnings("all") class Fields {
+ public static final java.lang.String I_AM_A_DVD_PLAYER = "iAmADvdPlayer";
+ public static final java.lang.String BUT_PRINT_ME_PLEASE = "butPrintMePlease";
+ <clinit>() {
+ }
+ private @java.lang.SuppressWarnings("all") Fields() {
+ super();
+ }
+ }
+ String iAmADvdPlayer;
+ int $skipMe;
+ static double skipMeToo;
+ @FieldNameConstants.Exclude int andMe;
+ String butPrintMePlease;
+ <clinit>() {
+ }
+ public FieldNameConstantsUppercased() {
+ super();
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/SuperBuilderWithGenericsAndToBuilder.java b/test/transform/resource/after-ecj/SuperBuilderWithGenericsAndToBuilder.java
index 107ee362..ce960d61 100644
--- a/test/transform/resource/after-ecj/SuperBuilderWithGenericsAndToBuilder.java
+++ b/test/transform/resource/after-ecj/SuperBuilderWithGenericsAndToBuilder.java
@@ -1,9 +1,10 @@
-import java.util.List;
+import java.util.Map;
public class SuperBuilderWithGenericsAndToBuilder {
public static @lombok.experimental.SuperBuilder(toBuilder = true) class Parent<A> {
public static abstract @java.lang.SuppressWarnings("all") class ParentBuilder<A, C extends Parent<A>, B extends ParentBuilder<A, C, B>> {
private @java.lang.SuppressWarnings("all") A field1;
- private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> items;
+ private @java.lang.SuppressWarnings("all") java.util.ArrayList<Integer> items$key;
+ private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> items$value;
public ParentBuilder() {
super();
}
@@ -13,7 +14,7 @@ public class SuperBuilderWithGenericsAndToBuilder {
}
private static @java.lang.SuppressWarnings("all") <A>void $fillValuesFromInstanceIntoBuilder(final Parent<A> instance, final ParentBuilder<A, ?, ?> b) {
b.field1(instance.field1);
- b.items(((instance.items == null) ? java.util.Collections.emptyList() : instance.items));
+ b.items(((instance.items == null) ? java.util.Collections.emptyMap() : instance.items));
}
protected abstract @java.lang.SuppressWarnings("all") B self();
public abstract @java.lang.SuppressWarnings("all") C build();
@@ -21,25 +22,39 @@ public class SuperBuilderWithGenericsAndToBuilder {
this.field1 = field1;
return self();
}
- public @java.lang.SuppressWarnings("all") B item(final String item) {
- if ((this.items == null))
- this.items = new java.util.ArrayList<String>();
- this.items.add(item);
+ public @java.lang.SuppressWarnings("all") B item(final Integer itemKey, final String itemValue) {
+ if ((this.items$key == null))
+ {
+ this.items$key = new java.util.ArrayList<Integer>();
+ this.items$value = new java.util.ArrayList<String>();
+ }
+ this.items$key.add(itemKey);
+ this.items$value.add(itemValue);
return self();
}
- public @java.lang.SuppressWarnings("all") B items(final java.util.Collection<? extends String> items) {
- if ((this.items == null))
- this.items = new java.util.ArrayList<String>();
- this.items.addAll(items);
+ public @java.lang.SuppressWarnings("all") B items(final java.util.Map<? extends Integer, ? extends String> items) {
+ if ((this.items$key == null))
+ {
+ this.items$key = new java.util.ArrayList<Integer>();
+ this.items$value = new java.util.ArrayList<String>();
+ }
+ for (java.util.Map.Entry<? extends Integer, ? extends String> $lombokEntry : items.entrySet())
+ {
+ this.items$key.add($lombokEntry.getKey());
+ this.items$value.add($lombokEntry.getValue());
+ }
return self();
}
public @java.lang.SuppressWarnings("all") B clearItems() {
- if ((this.items != null))
- this.items.clear();
+ if ((this.items$key != null))
+ {
+ this.items$key.clear();
+ this.items$value.clear();
+ }
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
- return (((("SuperBuilderWithGenericsAndToBuilder.Parent.ParentBuilder(field1=" + this.field1) + ", items=") + this.items) + ")");
+ return (((((("SuperBuilderWithGenericsAndToBuilder.Parent.ParentBuilder(field1=" + this.field1) + ", items$key=") + this.items$key) + ", items$value=") + this.items$value) + ")");
}
}
private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl<A> extends ParentBuilder<A, Parent<A>, ParentBuilderImpl<A>> {
@@ -54,20 +69,23 @@ public class SuperBuilderWithGenericsAndToBuilder {
}
}
A field1;
- @lombok.Singular List<String> items;
+ @lombok.Singular Map<Integer, String> items;
protected @java.lang.SuppressWarnings("all") Parent(final ParentBuilder<A, ?, ?> b) {
super();
this.field1 = b.field1;
- java.util.List<String> items;
- switch (((b.items == null) ? 0 : b.items.size())) {
+ java.util.Map<Integer, String> items;
+ switch (((b.items$key == null) ? 0 : b.items$key.size())) {
case 0 :
- items = java.util.Collections.emptyList();
+ items = java.util.Collections.emptyMap();
break;
case 1 :
- items = java.util.Collections.singletonList(b.items.get(0));
+ items = java.util.Collections.singletonMap(b.items$key.get(0), b.items$value.get(0));
break;
default :
- items = java.util.Collections.unmodifiableList(new java.util.ArrayList<String>(b.items));
+ items = new java.util.LinkedHashMap<Integer, String>(((b.items$key.size() < 0x40000000) ? ((1 + b.items$key.size()) + ((b.items$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE));
+ for (int $i = 0;; ($i < b.items$key.size()); $i ++)
+ items.put(b.items$key.get($i), b.items$value.get($i));
+ items = java.util.Collections.unmodifiableMap(items);
}
this.items = items;
}
@@ -129,6 +147,6 @@ public class SuperBuilderWithGenericsAndToBuilder {
super();
}
public static void test() {
- Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item("").build().toBuilder().build();
+ Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item(5, "").build().toBuilder().build();
}
}
diff --git a/test/transform/resource/after-ecj/ValDelegateMethodReference.java b/test/transform/resource/after-ecj/ValDelegateMethodReference.java
new file mode 100644
index 00000000..cfd0dab2
--- /dev/null
+++ b/test/transform/resource/after-ecj/ValDelegateMethodReference.java
@@ -0,0 +1,58 @@
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Delegate;
+import lombok.val;
+import java.util.function.Function;
+public class ValDelegateMethodReference {
+ public ValDelegateMethodReference() {
+ super();
+ }
+ public void config() {
+ final @val Column<Entity, java.lang.String> column = createColumn(Entity::getValue);
+ }
+ private <V>Column<Entity, V> createColumn(Function<Entity, V> func) {
+ return new Column<>(func);
+ }
+}
+class Column<T, V> {
+ public Column(Function<T, V> vp) {
+ super();
+ }
+}
+class Entity {
+ private @Delegate MyDelegate innerDelegate;
+ Entity() {
+ super();
+ }
+ public @java.lang.SuppressWarnings("all") java.lang.Boolean getABoolean() {
+ return this.innerDelegate.getABoolean();
+ }
+ public @java.lang.SuppressWarnings("all") java.lang.String getValue() {
+ return this.innerDelegate.getValue();
+ }
+ public @java.lang.SuppressWarnings("all") void setABoolean(final java.lang.Boolean aBoolean) {
+ this.innerDelegate.setABoolean(aBoolean);
+ }
+ public @java.lang.SuppressWarnings("all") void setValue(final java.lang.String value) {
+ this.innerDelegate.setValue(value);
+ }
+}
+@Getter @Setter class MyDelegate {
+ private String value;
+ private Boolean aBoolean;
+ MyDelegate() {
+ super();
+ }
+ public @java.lang.SuppressWarnings("all") String getValue() {
+ return this.value;
+ }
+ public @java.lang.SuppressWarnings("all") Boolean getABoolean() {
+ return this.aBoolean;
+ }
+ public @java.lang.SuppressWarnings("all") void setValue(final String value) {
+ this.value = value;
+ }
+ public @java.lang.SuppressWarnings("all") void setABoolean(final Boolean aBoolean) {
+ this.aBoolean = aBoolean;
+ }
+}
diff --git a/test/transform/resource/before/BuilderSimple.java b/test/transform/resource/before/BuilderSimple.java
index 83c89713..d0a786db 100644
--- a/test/transform/resource/before/BuilderSimple.java
+++ b/test/transform/resource/before/BuilderSimple.java
@@ -1,6 +1,6 @@
import java.util.List;
-@lombok.Builder
+@lombok.Builder(access = lombok.AccessLevel.PROTECTED)
class BuilderSimple<T> {
private final int noshow = 0;
private final int yes;
diff --git a/test/transform/resource/before/FieldNameConstantsUppercased.java b/test/transform/resource/before/FieldNameConstantsUppercased.java
new file mode 100644
index 00000000..674cb7f1
--- /dev/null
+++ b/test/transform/resource/before/FieldNameConstantsUppercased.java
@@ -0,0 +1,12 @@
+//CONF: lombok.fieldNameConstants.uppercase = true
+import lombok.experimental.FieldNameConstants;
+import lombok.AccessLevel;
+
+@FieldNameConstants(level = AccessLevel.PACKAGE)
+public class FieldNameConstantsUppercased {
+ String iAmADvdPlayer;
+ int $skipMe;
+ static double skipMeToo;
+ @FieldNameConstants.Exclude int andMe;
+ String butPrintMePlease;
+}
diff --git a/test/transform/resource/before/SuperBuilderWithGenericsAndToBuilder.java b/test/transform/resource/before/SuperBuilderWithGenericsAndToBuilder.java
index dae68034..1f2caf6d 100644
--- a/test/transform/resource/before/SuperBuilderWithGenericsAndToBuilder.java
+++ b/test/transform/resource/before/SuperBuilderWithGenericsAndToBuilder.java
@@ -1,10 +1,10 @@
-import java.util.List;
+import java.util.Map;
public class SuperBuilderWithGenericsAndToBuilder {
@lombok.experimental.SuperBuilder(toBuilder = true)
public static class Parent<A> {
A field1;
- @lombok.Singular List<String> items;
+ @lombok.Singular Map<Integer, String> items;
}
@lombok.experimental.SuperBuilder(toBuilder = true)
@@ -13,6 +13,6 @@ public class SuperBuilderWithGenericsAndToBuilder {
}
public static void test() {
- Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item("").build().toBuilder().build();
+ Child<Integer> x = Child.<Integer>builder().field3(0.0).field1(5).item(5, "").build().toBuilder().build();
}
}
diff --git a/test/transform/resource/before/ValDelegateMethodReference.java b/test/transform/resource/before/ValDelegateMethodReference.java
new file mode 100644
index 00000000..7adc402a
--- /dev/null
+++ b/test/transform/resource/before/ValDelegateMethodReference.java
@@ -0,0 +1,35 @@
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Delegate;
+import lombok.val;
+
+import java.util.function.Function;
+
+public class ValDelegateMethodReference {
+
+ public void config() {
+ val column = createColumn(Entity::getValue);
+ }
+
+ private <V> Column<Entity, V> createColumn(Function<Entity, V> func) {
+ return new Column<>(func);
+ }
+
+}
+
+class Column<T, V> {
+ public Column(Function<T, V> vp) {}
+}
+
+class Entity {
+ @Delegate
+ private MyDelegate innerDelegate;
+}
+
+@Getter
+@Setter
+class MyDelegate {
+ private String value;
+ private Boolean aBoolean;
+} \ No newline at end of file
diff --git a/website/extra/htaccess b/website/extra/htaccess
index e7b54de4..d2c7a292 100644
--- a/website/extra/htaccess
+++ b/website/extra/htaccess
@@ -67,3 +67,7 @@ RewriteRule ^features/experimental/index(\.html)?/?$ /features/experimental/all
RewriteRule ^features/experimental/${pg?no_esc}$ /features/experimental/${pg?no_esc}.html [L,END]
RewriteRule ^features/experimental/${pg?no_esc}(\.html)?/?$ /features/experimental/${pg?no_esc} [NC,R=301]
</#list>
+
+RewriteRule ^presentations/7lessons$ /presentations/7lessons.html [L,END]
+RewriteRule ^presentations/7lessons(\.html)?/?$ /presentations/7lessons [NC,R=301]
+RewriteRule ^presentations/7mistakes(\.html)?/?$ /presentations/7lessons [NC,R=301]
diff --git a/website/resources/js/main.js b/website/resources/js/main.js
index 5608a3c3..eaaf2df5 100644
--- a/website/resources/js/main.js
+++ b/website/resources/js/main.js
@@ -94,7 +94,23 @@
});
}
+ function seekVideo() {
+ var t = window.location.hash;
+ if (!t) return;
+ var s = /^#?(?:(\d\d?):)?(\d\d?):(\d\d?)$/.exec(t);
+ if (!s) return;
+ var videoj = $("#presentationVideo");
+ if (!videoj || videoj.length == 0) return;
+ var video = videoj[0];
+ var h = parseInt(s[1]);
+ if (!h) h = 0;
+ var m = parseInt(s[2]);
+ var s = parseInt(s[3]);
+ video.currentTime = (((h * 60) + m) * 60) + s;
+ }
+
$(ajaxFeaturePages);
$(clickToTap);
$(clickForVideo);
+ $(seekVideo);
})($);
diff --git a/website/templates/credits.html b/website/templates/credits.html
index 3390d762..b5c033ad 100644
--- a/website/templates/credits.html
+++ b/website/templates/credits.html
@@ -29,6 +29,8 @@
</li><li>
<strong>Tor Norbye</strong>, <strong>Jan Lahoda</strong>, and <strong>Petr Jiricka</strong> for helping out with Netbeans internals and/or javac.
</li><li>
+ <strong>nqzero</strong> for the <a href="https://github.com/nqzero/permit-reflect">permit-reflect</a> library, whose ideas are also used in lombok.
+ </li><li>
All contributors who submitted patches or helped answering questions!</li>
</ul>
diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html
index 0818f9d2..4fe416ee 100644
--- a/website/templates/features/Builder.html
+++ b/website/templates/features/Builder.html
@@ -12,6 +12,8 @@
<code>@Builder.Default</code> functionality was added in lombok v1.16.16.
</p><p>
<code>@Builder(builderMethodName = "")</code> is legal (and will suppress generation of the builder method) starting with lombok v1.18.8.
+ </p><p>
+ <code>@Builder(access = AccessLevel.PACKAGE)</code> is legal (and will generate the builder class, the builder method, etc with the indicated access level) starting with lombok v1.18.8.
</p>
</@f.history>
@@ -64,10 +66,12 @@
The <em>builder()</em> method's name (default: <code>"builder"</code>)
</li><li>
If you want <code>toBuilder()</code> (default: no)
+ </li><li>
+ The access level of all generated elements (default: <code>public</code>).
</li>
</ul>
Example usage where all options are changed from their defaults:<br />
- <code>@Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld", toBuilder = true)</code><br />
+ <code>@Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld", toBuilder = true, access = AccessLevel.PRIVATE)</code><br />
</p>
</@f.overview>
@@ -194,6 +198,9 @@ public class JacksonExample {
<code>builder</code> method if you just want this functionality, by using: <code>@Builder(toBuilder = true, builderMethodName = "")</code>.
</p><p>
Due to a peculiar way javac processes static imports, trying to do a non-star static import of the static <code>builder()</code> method won't work. Either use a star static import: `import static TypeThatHasABuilder.*;` or don't statically import the <code>builder</code> method.
+ </p><p>
+ If setting the access level to <code>PROTECTED</code>, all methods generated inside the builder class are actually generated as <code>public</code>; the meaning of the
+ <code>protected</code> keyword is different inside the inner class, and the precise behaviour that <code>PROTECTED</code> would indicate (access by any source in the same package is allowed, as well as any subclasses <em>from the outer class, marked with <code>@Builder</code></em> is not possible, and marking the inner members <code>public</code> is as close as we can get.
</p>
</@f.smallPrint>
</@f.scaffold>
diff --git a/website/templates/features/Value.html b/website/templates/features/Value.html
index 5fe188b3..5d97a7b8 100644
--- a/website/templates/features/Value.html
+++ b/website/templates/features/Value.html
@@ -17,7 +17,7 @@
</p><p>
In practice, <code>@Value</code> is shorthand for: <code>final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter</code>, except that explicitly including an implementation of any of the relevant methods simply means that part won't be generated and no warning will be emitted. For example, if you write your own <code>toString</code>, no error occurs, and lombok will not generate a <code>toString</code>. Also, <em>any</em> explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add <code>@AllArgsConstructor</code> to the class. You can mark any constructor or method with <code>@lombok.experimental.Tolerate</code> to hide them from lombok.
</p><p>
- It is possible to override the final-by-default and private-by-default behavior using either an explicit access level on a field, or by using the <code>@NonFinal</code> or <code>@PackagePrivate</code> annotations.<br />
+ It is possible to override the final-by-default and private-by-default behavior using either an explicit access level on a field, or by using the <code>@NonFinal</code> or <code>@PackagePrivate</code> annotations. <code>@NonFinal</code> can also be used on a class to remove the final keyword. <br />
It is possible to override any default behavior for any of the 'parts' that make up <code>@Value</code> by explicitly using that annotation.
</p>
</@f.overview>
diff --git a/website/templates/features/configuration.html b/website/templates/features/configuration.html
index 7a15f252..bf224108 100644
--- a/website/templates/features/configuration.html
+++ b/website/templates/features/configuration.html
@@ -30,9 +30,9 @@
</dt><dd>
If set to <code>true</code>, generated setters and getters will simply be named the same as the field name, without a <code>get</code> or <code>set</code> prefix.
</dd><dt>
- <code>llombok.anyConstructor.addConstructorProperties</code>
+ <code>lombok.anyConstructor.addConstructorProperties</code>
</dt><dd>
- If <code>true</code>, lombok will generate a <code>@java.beans.ConstructorProperties</code> annotation when generating constructors. This is particularly useful for GWT and Android development. Note that you'll need to depend on module 'java.desktop' if you're using jigsaw.
+ If <code>true</code>, lombok will generate a <code>@java.beans.ConstructorProperties</code> annotation when generating constructors. Note that you'll need to depend on module 'java.desktop' if you're using jigsaw.
</dd><dt>
<code>lombok.log.fieldName</code>
</dt><dd>
diff --git a/website/templates/features/experimental/FieldNameConstants.html b/website/templates/features/experimental/FieldNameConstants.html
index 1cbef32a..e88b7670 100644
--- a/website/templates/features/experimental/FieldNameConstants.html
+++ b/website/templates/features/experimental/FieldNameConstants.html
@@ -6,6 +6,8 @@
@FieldNameConstants was introduced as experimental feature in lombok v1.16.22.
</p><p>
@FieldNameConstants was redesigned in lombok v1.18.4.
+ </p><p>
+ The <em>lombok.config</em> option <code>lombok.fieldNameConstants.uppercase = true</code> was added in lombok v1.18.8.
</p>
</@f.history>
@@ -20,7 +22,7 @@
<@f.overview>
<p>
- The <code>@FieldNameConstants</code> annotation generates an inner type which contains 1 constant for each field in your class; either string constants (fields marked <code>public static final</code>, of type <code>java.lang.String</code>) or if you prefer, an enum type with 1 value for each field - write <code>@FieldNameConstants(asEnum = true)</code> for the enum variant. <code>@FieldNameConstants</code> is useful for various marshalling and serialization frameworks. The constant field (whether enum value or string constant) always has the exact same name as the field, capitalization and all.
+ The <code>@FieldNameConstants</code> annotation generates an inner type which contains 1 constant for each field in your class; either string constants (fields marked <code>public static final</code>, of type <code>java.lang.String</code>) or if you prefer, an enum type with 1 value for each field - write <code>@FieldNameConstants(asEnum = true)</code> for the enum variant. <code>@FieldNameConstants</code> is useful for various marshalling and serialization frameworks. The constant field (whether enum value or string constant) always has the exact same name as the field, capitalization and all, unless you set the <code>lombok.fieldNameConstants.uppercase = true</code> option in your <code>lombok.config</code> file; in that case lombok will try to <code>UPPER_CASE</code> the name.
</p><p>
The generated inner type is by default called <code>Fields</code> and is <code>public</code>. You can modify this via <code>@FieldNameConstants(innerTypeName = "FieldNames", access = AccessLevel.PACKAGE)</code> for example. The default inner type name can also be modified via configuration key <code>lombok.fieldNameConstants.innerTypeName</code>. The generated fields are always <code>public</code>.
</p><p>
@@ -39,6 +41,10 @@
<code>lombok.fieldNameConstants.innerTypeName</code> = <em>a string</em> (default: 'Fields')
</dt><dd>
The name of the inner type generated by lombok can be controlled with this configuration key.
+ </dd><dt>
+ <code>lombok.fieldNameConstants.uppercase</code> = [<code>true</code> | <code>false</code>] (default: false)
+ </dt><dd>
+ If <code>true</code>, attempt to uppercase the generated fields.
</dd>
</@f.confKeys>
diff --git a/website/templates/main.html b/website/templates/main.html
index fc925d61..03073436 100644
--- a/website/templates/main.html
+++ b/website/templates/main.html
@@ -25,7 +25,7 @@
</video>
<div class="row">
<div class="text-center">
- <a href="http://jnb.ociweb.com/jnb/jnbJan2010.html">Show me a text and images based explanation and tutorial instead!</a>
+ <a href="https://objectcomputing.com/resources/publications/sett/january-2010-reducing-boilerplate-code-with-project-lombok">Show me a text and images based explanation and tutorial instead!</a>
</div>
</div>
</div>
diff --git a/website/templates/presentations/7lessons.html b/website/templates/presentations/7lessons.html
new file mode 100644
index 00000000..3027fbad
--- /dev/null
+++ b/website/templates/presentations/7lessons.html
@@ -0,0 +1,25 @@
+<#import "../_scaffold.html" as main>
+<@main.scaffold>
+ <div class="page-header top5">
+ <div class="row text-center">
+ <@main.h1 title="The 7 biggest mistakes we made in Project Lombok" />
+ <p>
+ A presentation by Lombok's 2 core authors: Roel Spilker and Reinier Zwitserloot.<br />
+ We talk about the 7 biggest mistakes we made managing an open source project for the past 10 years.<br />
+ First given at <a href="https://programm.javaland.eu/2019/#/scheduledEvent/579921">Javaland (in Brühl, Germany) on March 19th, 2019</a>. Total length: 40 minutes.
+ </p>
+ </div>
+ <div class="video text-center">
+ <video id="presentationVideo" width="640" height="360" poster="/presentations/7lessons-poster.jpg" controls="controls" preload="none">
+ <source src="https://projectlombok.org/presentations/7lessons-vp9.webm" type="video/webm" />
+ <source src="https://projectlombok.org/presentations/7lessons.webm" type="video/webm" />
+ <source src="https://projectlombok.org/presentations/7lessons.mp4" type="video/mp4" />
+ <@main.h1 title="Can't watch the video?" />
+ <p>
+ You can download it and watch it with, for example, <a href="https://www.videolan.org/vlc/index.html">The open source VLC media player</a>:<br />
+ <a href="/videos/7lessons.mp4">Download: 7 biggest mistakes we made in Project Lombok</a>
+ </p>
+ </video>
+ </div>
+ </div>
+</@main.scaffold>