Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional support/map put methods #14

Merged
merged 3 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.avaje.recordbuilder.internal;

import static io.avaje.recordbuilder.internal.APContext.elements;
import static io.avaje.recordbuilder.internal.Templates.classTemplate;
import static java.util.stream.Collectors.joining;

import java.text.MessageFormat;
import java.util.List;

import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;

// TODO better name?
public class ClassBodyBuilder {

static String createClassStart(TypeElement type, boolean isImported) {

final var components = type.getRecordComponents();
final var packageName =
elements().getPackageOf(type).getQualifiedName().toString()
+ (isImported ? ".builder" : "");
final var shortName = type.getSimpleName().toString();
if (type.getEnclosingElement() instanceof TypeElement) {
isImported = true;
}
final RecordModel rm = new RecordModel(type, isImported, components);
rm.initialImports();
final String fieldString = rm.fields();
final var imports = rm.importsFormat();
final var numberOfComponents = components.size();

// String fieldString = fields(components);
final String constructorParams = constructorParams(components, numberOfComponents > 5);
final String constructorBody = constructorBody(components);
final String builderFrom =
builderFrom(components).transform(s -> numberOfComponents > 5 ? "\n " + s : s);
final String build =
build(components).transform(s -> numberOfComponents > 6 ? "\n " + s : s);
return classTemplate(
packageName,
imports,
shortName,
fieldString,
constructorParams,
constructorBody,
builderFrom,
build);
}

private static String constructorParams(
List<? extends RecordComponentElement> components, boolean verticalArgs) {

return components.stream()
.map(r -> UType.parse(r.asType()).shortType() + " " + r.getSimpleName())
.collect(joining(verticalArgs ? ",\n " : ", "))
.transform(s -> verticalArgs ? "\n " + s : s);
}

private static String constructorBody(List<? extends RecordComponentElement> components) {
return components.stream()
.map(RecordComponentElement::getSimpleName)
.map(s -> MessageFormat.format("this.{0} = {0};", s))
.collect(joining("\n "));
}

private static String builderFrom(List<? extends RecordComponentElement> components) {
return components.stream()
.map(RecordComponentElement::getSimpleName)
.map("from.%s()"::formatted)
.collect(joining(", "));
}

private static String build(List<? extends RecordComponentElement> components) {
return components.stream().map(RecordComponentElement::getSimpleName).collect(joining(", "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package io.avaje.recordbuilder.internal;

import java.io.ObjectOutputStream.PutField;
import java.util.HashMap;
import java.util.Map;

public class InitMap {
private static final Map<String, String> defaultsMap = new HashMap<>();

static {
// TODO add the rest of the collections
final var util = "java.util.";
final var initDiamond = "new java.util.%s<>()";
// optional
put(util + "Optional", util + "Optional.empty()");
put(util + "OptionalInt", util + "OptionalInt.empty()");
put(util + "OptionalDouble", util + "OptionalDouble.empty()");
put(util + "OptionalLong", util + "OptionalLong.empty()");

put(util + "Collection", initDiamond.formatted("ArrayList"));
put(util + "SequencedCollection", initDiamond.formatted("ArrayList"));
// list
put(util + "List", initDiamond.formatted("ArrayList"));
put(util + "ArrayList", initDiamond.formatted("ArrayList"));
put(util + "LinkedList", initDiamond.formatted("LinkedList"));
// set
put(util + "Set", initDiamond.formatted("HashSet"));
put(util + "SequencedSet", initDiamond.formatted("LinkedHashSet"));
put(util + "HashSet", initDiamond.formatted("HashSet"));
put(util + "TreeSet", initDiamond.formatted("TreeSet"));
put(util + "SortedSet", initDiamond.formatted("TreeSet"));
put(util + "NavigableSet", initDiamond.formatted("TreeSet"));
put(util + "LinkedHashSet", initDiamond.formatted("LinkedHashSet"));
// map
put(util + "Map", initDiamond.formatted("HashMap"));
put(util + "SequencedMap", initDiamond.formatted("LinkedHashMap"));
put(util + "HashMap", initDiamond.formatted("HashMap"));
put(util + "LinkedHashMap", initDiamond.formatted("LinkedHashMap"));
put(util + "TreeMap", initDiamond.formatted("TreeMap"));
put(util + "SortedMap", initDiamond.formatted("TreeMap"));
put(util + "NavigableMap", initDiamond.formatted("TreeMap"));

// queue

// deque
}

static void put(String key, String value) {

defaultsMap.put(key, value);
}

static String get(String key) {
return defaultsMap.get(key);
}

public static void putAll(Map<String, String> map) {
defaultsMap.putAll(map);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.joining;

import java.lang.invoke.VarHandle;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.lang.model.element.RecordComponentElement;
Expand All @@ -23,7 +25,12 @@ final class RecordModel {

private final Set<String> importTypes = new TreeSet<>();

RecordModel(TypeElement type, boolean isImported, List<? extends RecordComponentElement> components) {
// Create a Pattern object
Pattern JAVA_UTIL = Pattern.compile("new\\s+(java\\.util\\.[A-Za-z]+)");
Pattern OPTIONAL = Pattern.compile("(java\\.util\\.[A-Za-z]+)");

RecordModel(
TypeElement type, boolean isImported, List<? extends RecordComponentElement> components) {
this.type = type;
this.isImported = isImported;
this.components = components;
Expand All @@ -47,7 +54,7 @@ void initialImports() {
importTypes.addAll(types);
}

String fields(Map<String, String> defaultsMap) {
String fields() {
final var builder = new StringBuilder();
for (final var element : components) {
final var uType = UType.parse(element.asType());
Expand All @@ -57,21 +64,29 @@ String fields(Map<String, String> defaultsMap) {
if (initPrism != null) {
defaultVal = " = " + initPrism.value();
} else {
final String dt = defaultsMap.get(uType.mainType());
final String dt = InitMap.get(uType.mainType());
if (dt != null) {
var javaUtil = dt.startsWith("java.util");
if (javaUtil) {
importTypes.add(dt);
defaultVal = " = new " + ProcessorUtils.shortType(dt) + "<>()";
var javaUtil = dt.startsWith("new java.util");
var optional = dt.startsWith("java.util.Optional");
if (javaUtil || optional) {
if (optional) {
var matcher = OPTIONAL.matcher(dt);
matcher.find();
importTypes.add(matcher.group(0));
} else {
var matcher = JAVA_UTIL.matcher(dt);
matcher.find();
importTypes.add(matcher.group(1));
}
defaultVal = " = " + dt.replace("java.util.", "");
} else {
defaultVal = " = " + dt;
}
}
}

builder.append(
" private %s %s%s;\n"
.formatted(uType.shortType(), element.getSimpleName(), defaultVal));
" private %s %s%s;\n".formatted(uType.shortType(), element.getSimpleName(), defaultVal));
}

return builder.toString();
Expand Down
Loading
Loading