mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-15 00:17:45 +00:00
[fixes #2083] adds feature ‘access level’ to @Builder
This commit is contained in:
1 parent
ec04d9d7f0
commit
a318029830
19 files changed
+201
-167
No files matched your search
@@ -3,6 +3,7 @@ Lombok Changelog
|
||||
|
||||
### v1.18.7 "Edgy Guinea Pig"
|
||||
* 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)
|
||||
|
||||
@@ -146,6 +146,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}.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -889,7 +889,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -99,16 +100,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 +123,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 +134,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 +167,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));
|
||||
|
||||
+13
-12
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
@@ -135,21 +136,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 +180,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 +237,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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -862,7 +862,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,9 @@ public class JavacSingularsRecipes {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected abstract String getAddMethodName();
|
||||
|
||||
|
||||
protected abstract int getTypeArgumentsCount();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -66,8 +67,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 +76,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 +86,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 +99,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 +113,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected JCExpression getPluralMethodParamType(JavacNode builderType) {
|
||||
JCExpression paramType;
|
||||
@@ -124,7 +125,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 +172,9 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
|
||||
}
|
||||
|
||||
protected abstract LombokImmutableList<String> getArgumentSuffixes();
|
||||
|
||||
|
||||
protected abstract String getAddAllTypeName();
|
||||
|
||||
|
||||
@Override
|
||||
protected int getTypeArgumentsCount() {
|
||||
return getArgumentSuffixes().size();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,14 @@ 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 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 +91,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 +108,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 +121,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 +130,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 +150,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 +170,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;
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user