Compare commits

...

1 Commits

Author SHA1 Message Date
Jordan Zimmerman
038ea4797a Fix addSingleItemCollectionBuilders when useImmutableCollections is false
- Removed `SingleItemsMetaDataMode.STANDARD` as it wasn't used
- Removed `needs*MutableMaker` - always add them when corresponding `needs*Shim` is true
- Merged `addMutableMakers()` into `addShims()`
- Always use mutable makers when addSingleItemCollectionBuilders is true

Fixes #129
2022-10-19 16:12:15 +02:00
4 changed files with 88 additions and 66 deletions

View File

@@ -42,10 +42,6 @@ class CollectionBuilderUtils {
private boolean needsSetShim; private boolean needsSetShim;
private boolean needsCollectionShim; private boolean needsCollectionShim;
private boolean needsListMutableMaker;
private boolean needsMapMutableMaker;
private boolean needsSetMutableMaker;
private static final Class<?> listType = List.class; private static final Class<?> listType = List.class;
private static final Class<?> mapType = Map.class; private static final Class<?> mapType = Map.class;
private static final Class<?> setType = Set.class; private static final Class<?> setType = Set.class;
@@ -93,7 +89,6 @@ class CollectionBuilderUtils {
} }
enum SingleItemsMetaDataMode { enum SingleItemsMetaDataMode {
STANDARD,
STANDARD_FOR_SETTER, STANDARD_FOR_SETTER,
EXCLUDE_WILDCARD_TYPES EXCLUDE_WILDCARD_TYPES
} }
@@ -122,8 +117,6 @@ class CollectionBuilderUtils {
var hasWildcardTypeArguments = hasWildcardTypeArguments(parameterizedTypeName, typeArgumentQty); var hasWildcardTypeArguments = hasWildcardTypeArguments(parameterizedTypeName, typeArgumentQty);
if (collectionClass != null) { if (collectionClass != null) {
return switch (mode) { return switch (mode) {
case STANDARD -> singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass, typeArgumentQty);
case STANDARD_FOR_SETTER -> { case STANDARD_FOR_SETTER -> {
if (hasWildcardTypeArguments) { if (hasWildcardTypeArguments) {
yield Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, component.typeName())); yield Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, component.typeName()));
@@ -160,18 +153,15 @@ class CollectionBuilderUtils {
} }
void addShimCall(CodeBlock.Builder builder, RecordClassType component) { void addShimCall(CodeBlock.Builder builder, RecordClassType component) {
if (useImmutableCollections) { if (useImmutableCollections || addSingleItemCollectionBuilders) {
if (isList(component)) { if (isList(component)) {
needsListShim = true; needsListShim = true;
needsListMutableMaker = true;
builder.add("$L($L)", listShimName, component.name()); builder.add("$L($L)", listShimName, component.name());
} else if (isMap(component)) { } else if (isMap(component)) {
needsMapShim = true; needsMapShim = true;
needsMapMutableMaker = true;
builder.add("$L($L)", mapShimName, component.name()); builder.add("$L($L)", mapShimName, component.name());
} else if (isSet(component)) { } else if (isSet(component)) {
needsSetShim = true; needsSetShim = true;
needsSetMutableMaker = true;
builder.add("$L($L)", setShimName, component.name()); builder.add("$L($L)", setShimName, component.name());
} else if (component.rawTypeName().equals(collectionTypeName)) { } else if (component.rawTypeName().equals(collectionTypeName)) {
needsCollectionShim = true; needsCollectionShim = true;
@@ -211,10 +201,6 @@ class CollectionBuilderUtils {
} }
void addShims(TypeSpec.Builder builder) { void addShims(TypeSpec.Builder builder) {
if (!useImmutableCollections) {
return;
}
if (needsListShim) { if (needsListShim) {
builder.addMethod(buildShimMethod(listShimName, listTypeName, collectionType, parameterizedListType, tType)); builder.addMethod(buildShimMethod(listShimName, listTypeName, collectionType, parameterizedListType, tType));
} }
@@ -227,24 +213,19 @@ class CollectionBuilderUtils {
if (needsCollectionShim) { if (needsCollectionShim) {
builder.addMethod(buildCollectionsShimMethod()); builder.addMethod(buildCollectionsShimMethod());
} }
} if (addSingleItemCollectionBuilders) {
if (needsListShim) {
void addMutableMakers(TypeSpec.Builder builder) {
if (!useImmutableCollections) {
return;
}
if (needsListMutableMaker) {
builder.addMethod(buildMutableMakerMethod(listMakerMethodName, mutableListSpec.name, parameterizedListType, tType));
builder.addType(mutableListSpec); builder.addType(mutableListSpec);
builder.addMethod(buildMutableMakerMethod(listMakerMethodName, mutableListSpec.name, parameterizedListType, tType));
} }
if (needsSetMutableMaker) { if (needsSetShim) {
builder.addMethod(buildMutableMakerMethod(setMakerMethodName, mutableSetSpec.name, parameterizedSetType, tType));
builder.addType(mutableSetSpec); builder.addType(mutableSetSpec);
builder.addMethod(buildMutableMakerMethod(setMakerMethodName, mutableSetSpec.name, parameterizedSetType, tType));
} }
if (needsMapMutableMaker) { if (needsMapShim) {
builder.addMethod(buildMutableMakerMethod(mapMakerMethodName, mutableMapSpec.name, parameterizedMapType, kType, vType));
builder.addType(mutableMapSpec); builder.addType(mutableMapSpec);
builder.addMethod(buildMutableMakerMethod(mapMakerMethodName, mutableMapSpec.name, parameterizedMapType, kType, vType));
}
} }
} }

View File

@@ -15,12 +15,8 @@
*/ */
package io.soabase.recordbuilder.processor; package io.soabase.recordbuilder.processor;
import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.EXCLUDE_WILDCARD_TYPES; import com.squareup.javapoet.*;
import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.STANDARD_FOR_SETTER; import io.soabase.recordbuilder.core.RecordBuilder;
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName;
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation;
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.*; import javax.lang.model.element.*;
@@ -33,8 +29,12 @@ import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.squareup.javapoet.*; import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.EXCLUDE_WILDCARD_TYPES;
import io.soabase.recordbuilder.core.RecordBuilder; import static io.soabase.recordbuilder.processor.CollectionBuilderUtils.SingleItemsMetaDataMode.STANDARD_FOR_SETTER;
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
import static io.soabase.recordbuilder.processor.ElementUtils.getWithMethodName;
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation;
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
class InternalRecordBuilderProcessor { class InternalRecordBuilderProcessor {
private final RecordBuilder.Options metaData; private final RecordBuilder.Options metaData;
@@ -107,11 +107,9 @@ class InternalRecordBuilderProcessor {
if (metaData.addConcreteSettersForOptional()) { if (metaData.addConcreteSettersForOptional()) {
add1ConcreteOptionalSetterMethod(component); add1ConcreteOptionalSetterMethod(component);
} }
var collectionMetaData = collectionBuilderUtils.singleItemsMetaData(component, EXCLUDE_WILDCARD_TYPES); collectionBuilderUtils.singleItemsMetaData(component, EXCLUDE_WILDCARD_TYPES).ifPresent(meta -> add1CollectionBuilders(meta, component));
collectionMetaData.ifPresent(meta -> add1CollectionBuilders(meta, component));
}); });
collectionBuilderUtils.addShims(builder); collectionBuilderUtils.addShims(builder);
collectionBuilderUtils.addMutableMakers(builder);
builderType = builder.build(); builderType = builder.build();
} }
@@ -806,13 +804,13 @@ class InternalRecordBuilderProcessor {
private void add1CollectionBuilders(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) { private void add1CollectionBuilders(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) {
if (collectionBuilderUtils.isList(component) || collectionBuilderUtils.isSet(component)) { if (collectionBuilderUtils.isList(component) || collectionBuilderUtils.isSet(component)) {
add1ListBuilder(meta, component); add1SingleItemsListBuilder(meta, component);
} else if (collectionBuilderUtils.isMap(component)) { } else if (collectionBuilderUtils.isMap(component)) {
add1MapBuilder(meta, component); add1SingleItemsMapBuilder(meta, component);
} }
} }
private void add1MapBuilder(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) { private void add1SingleItemsMapBuilder(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) {
/* /*
For a single map record component, add a methods similar to: For a single map record component, add a methods similar to:
@@ -836,15 +834,7 @@ class InternalRecordBuilderProcessor {
*/ */
for (var i = 0; i < 3; ++i) { for (var i = 0; i < 3; ++i) {
var codeBlockBuilder = CodeBlock.builder(); var codeBlockBuilder = CodeBlock.builder();
if (collectionBuilderUtils.isImmutableCollection(component)) { codeBlockBuilder.addStatement("this.$L = $L($L)", component.name(), collectionBuilderUtils.mutableMakerName(component), component.name());
codeBlockBuilder
.addStatement("this.$L = $L($L)", component.name(), collectionBuilderUtils.mutableMakerName(component), component.name());
} else {
codeBlockBuilder
.beginControlFlow("if (this.$L == null)", component.name())
.addStatement("this.$L = new $T<>()", component.name(), meta.singleItemCollectionClass())
.endControlFlow();
}
var methodSpecBuilder = MethodSpec.methodBuilder(metaData.singleItemBuilderPrefix() + capitalize(component.name())) var methodSpecBuilder = MethodSpec.methodBuilder(metaData.singleItemBuilderPrefix() + capitalize(component.name()))
.addJavadoc("Add to the internally allocated {@code HashMap} for {@code $L}\n", component.name()) .addJavadoc("Add to the internally allocated {@code HashMap} for {@code $L}\n", component.name())
.addModifiers(Modifier.PUBLIC) .addModifiers(Modifier.PUBLIC)
@@ -867,7 +857,7 @@ class InternalRecordBuilderProcessor {
} }
} }
private void add1ListBuilder(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) { private void add1SingleItemsListBuilder(CollectionBuilderUtils.SingleItemsMetaData meta, RecordClassType component) {
/* /*
For a single list or set record component, add methods similar to: For a single list or set record component, add methods similar to:
@@ -901,15 +891,7 @@ class InternalRecordBuilderProcessor {
parameter = ParameterizedTypeName.get(parameterClass, WildcardTypeName.subtypeOf(meta.typeArguments().get(0))); parameter = ParameterizedTypeName.get(parameterClass, WildcardTypeName.subtypeOf(meta.typeArguments().get(0)));
} }
var codeBlockBuilder = CodeBlock.builder(); var codeBlockBuilder = CodeBlock.builder();
if (collectionBuilderUtils.isImmutableCollection(component)) { codeBlockBuilder.addStatement("this.$L = $L($L)", component.name(), collectionBuilderUtils.mutableMakerName(component), component.name());
codeBlockBuilder
.addStatement("this.$L = $L($L)", component.name(), collectionBuilderUtils.mutableMakerName(component), component.name());
} else {
codeBlockBuilder
.beginControlFlow("if (this.$L == null)", component.name())
.addStatement("this.$L = new $T<>()", component.name(), meta.singleItemCollectionClass())
.endControlFlow();
}
codeBlockBuilder codeBlockBuilder
.add(addClockBlock.build()) .add(addClockBlock.build())
.addStatement("return this"); .addStatement("return this");

View File

@@ -0,0 +1,26 @@
/**
* Copyright 2019 Jordan Zimmerman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.soabase.recordbuilder.test.issue129;
import java.util.List;
import java.util.Map;
@RecordStyle
public record CombinedFields<K, V>(
Map<K, V> kvMap,
String combinedField,
List<String> lines) implements CombinedFieldsBuilder.Bean<K, V>, CombinedFieldsBuilder.With<K, V> {
}

View File

@@ -0,0 +1,33 @@
/**
* Copyright 2019 Jordan Zimmerman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.soabase.recordbuilder.test.issue129;
import io.soabase.recordbuilder.core.RecordBuilder;
import java.lang.annotation.*;
@RecordBuilder.Template(options = @RecordBuilder.Options(
addSingleItemCollectionBuilders = true,
addFunctionalMethodsToWith = true,
booleanPrefix = "is",
setterPrefix = "set",
beanClassName = "Bean"))
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
@Inherited
public @interface RecordStyle {
}