Skip to content

Commit

Permalink
implement parameterized builder
Browse files Browse the repository at this point in the history
  • Loading branch information
epkugelmass committed Feb 27, 2024
1 parent c9811e3 commit 7c00376
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 48 deletions.
27 changes: 14 additions & 13 deletions options.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,20 @@ The names used for generated methods, classes, etc. can be changed via the follo

## Miscellaneous

| option | details |
|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. |
| `@RecordBuilder.Options(publicBuilderConstructors = true/false)` | Makes the generated builder's constructors public. The default is `false`. |
| `@RecordBuilder.Options(builderClassModifiers = {}})` | Any additional `javax.lang.model.element.Modifier` you wish to apply to the builder. |
| `@RecordBuilder.Options(beanClassName = "Foo")` | If set, the Builder will contain an internal interface with this name. |
| `@RecordBuilder.Options(addClassRetainedGenerated = true/false)` | If true, generated classes are annotated with `RecordBuilderGenerated`. The default is `false`. |
| `@RecordBuilder.Options(addStaticBuilder = true/false)` | If true, a functional-style builder is added so that record instances can be instantiated without `new()`. The default is `true`. |
| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. |
| `@RecordBuilder.Options(addConcreteSettersForOptional = true/false)` | Add non-optional setter methods for optional record components. The default is `false`. |
| `@RecordBuilder.Options(useValidationApi = true/false)` | Pass built records through the Java Validation API if it's available in the classpath. The default is `false`. |
| `@RecordBuilder.Options(builderMode = BuilderMode.XXX)` | Whether to add standard builder, staged builder or both. The default is `BuilderMode.STANDARD`. |
| `@RecordBuilder.Options(onceOnlyAssignment = true/false)` | If true, attributes can be set/assigned only 1 time. Attempts to reassign/reset attributes will throw `java.lang.IllegalStateException`. The default is `false`. |
| option | details |
|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. |
| `@RecordBuilder.Options(publicBuilderConstructors = true/false)` | Makes the generated builder's constructors public. The default is `false`. |
| `@RecordBuilder.Options(parameterizedBuilder = true/false)` | Parameterizes the generated builder on the builder type itself. Builder setters will return the type parameter. This is useful when extending the builder. The default is `false`. | |
| `@RecordBuilder.Options(builderClassModifiers = {}})` | Any additional `javax.lang.model.element.Modifier` you wish to apply to the builder. |
| `@RecordBuilder.Options(beanClassName = "Foo")` | If set, the Builder will contain an internal interface with this name. |
| `@RecordBuilder.Options(addClassRetainedGenerated = true/false)` | If true, generated classes are annotated with `RecordBuilderGenerated`. The default is `false`. |
| `@RecordBuilder.Options(addStaticBuilder = true/false)` | If true, a functional-style builder is added so that record instances can be instantiated without `new()`. The default is `true`. |
| `@RecordBuilder.Options(inheritComponentAnnotations = true/false)` | If true, any annotations (if applicable) on record components are copied to the builder methods. The default is `true`. |
| `@RecordBuilder.Options(addConcreteSettersForOptional = true/false)` | Add non-optional setter methods for optional record components. The default is `false`. |
| `@RecordBuilder.Options(useValidationApi = true/false)` | Pass built records through the Java Validation API if it's available in the classpath. The default is `false`. |
| `@RecordBuilder.Options(builderMode = BuilderMode.XXX)` | Whether to add standard builder, staged builder or both. The default is `BuilderMode.STANDARD`. |
| `@RecordBuilder.Options(onceOnlyAssignment = true/false)` | If true, attributes can be set/assigned only 1 time. Attempts to reassign/reset attributes will throw `java.lang.IllegalStateException`. The default is `false`. |

### Staged Builders

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,12 @@
*/
boolean publicBuilderConstructors() default false;

/**
* Parameterizes the generated builder on the builder type itself. Builder setters will return the type
* parameter. This is useful when extending the builder.
*/
boolean parameterizedBuilder() default false;

/**
* Whether to add standard builder, staged builder or both
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static ClassType getClassType(ClassName builderClassName,
if (typeParameters.isEmpty()) {
return new ClassType(builderClassName, builderClassName.simpleName());
}
TypeName[] typeNames = typeParameters.stream().map(TypeVariableName::get).toArray(TypeName[]::new);
TypeName[] typeNames = toTypeVariableNames(typeParameters).toArray(TypeName[]::new);
return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName());
}

Expand All @@ -121,6 +121,10 @@ public static ClassType getClassTypeFromNames(ClassName builderClassName,
return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName());
}

public static List<TypeVariableName> toTypeVariableNames(List<? extends TypeParameterElement> typeParameters) {
return typeParameters.stream().map(TypeVariableName::get).toList();
}

public static RecordClassType getRecordClassType(ProcessingEnvironment processingEnv,
RecordComponentElement recordComponent, List<? extends AnnotationMirror> accessorAnnotations,
List<? extends AnnotationMirror> canonicalConstructorAnnotations) {
Expand Down
Loading

0 comments on commit 7c00376

Please sign in to comment.