Skip to content

Commit

Permalink
simplifications to the typing of basefluent
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Oct 20, 2023
1 parent 371398c commit ac109d6
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 198 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,10 @@ public class BuilderContext {
private final TypeDef visitorListenerInterface;
private final TypeDef visitorWiretapClass;
private final TypeDef delegatingVisitorClass;
private final TypeDef fluentInterface;
private final TypeDef builderInterface;
private final TypeDef nestedInterface;
private final TypeDef editableInterface;
private final TypeDef visitableInterface;
private TypeDef visitableInterface;
private final TypeDef visitableBuilderInterface;
private final TypeDef visitableMapClass;
private final TypeDef inlineableBase;
Expand Down Expand Up @@ -875,19 +874,6 @@ public BuilderContext(Elements elements, Types types, Boolean generateBuilderPac
.accept(new ReplacePackage("io.sundr.builder", builderPackage))
.build();

fluentInterface = new TypeDefBuilder()
.withNewModifiers().withPublic().endModifiers()
.withKind(Kind.INTERFACE)
.withPackageName("io.sundr.builder")
.withName("Fluent")
.addNewParameter()
.withName("F")
.withBounds(
new ClassRefBuilder().withFullyQualifiedName("io.sundr.builder.Fluent").withArguments(F.toReference()).build())
.endParameter()
.accept(new ReplacePackage("io.sundr.builder", builderPackage))
.build();

nestedInterface = new TypeDefBuilder()
.withNewModifiers().withPublic().endModifiers()
.withKind(Kind.INTERFACE)
Expand Down Expand Up @@ -983,16 +969,27 @@ public BuilderContext(Elements elements, Types types, Boolean generateBuilderPac
.accept(new ApplyImportsFromResources("io/sundr/builder/VisitableMap.java"))
.build();

// rebuild visitable now that visitableMapClass is available
visitableInterface = new TypeDefBuilder(visitableInterface)
.addNewMethod()
.withDefaultMethod(true)
.withNewModifiers().withPublic().endModifiers()
.withName("getVisitableMap")
.withReturnType(OPTIONAL.toReference(visitableMapClass.toReference()))
.endMethod()
.accept(new ReplacePackage("io.sundr.builder", builderPackage))
.accept(new ApplyMethodBlockFromResources("Visitable", "io/sundr/builder/Visitable.java", true))
.accept(new ApplyImportsFromResources("io/sundr/builder/Visitable.java"))
.build();

baseFluentClass = new TypeDefBuilder()
.withNewModifiers().withPublic().endModifiers()
.withKind(Kind.CLASS)
.withPackageName("io.sundr.builder")
.withName("BaseFluent")
.addNewParameter()
.withName("F")
.withBounds(fluentInterface.toReference(F.toReference()))
.endParameter()
.withImplementsList(fluentInterface.toReference(F.toReference()), visitableInterface.toReference(F.toReference()))

.addNewProperty()
.withNewModifiers().withPublic().withStatic().withFinal().endModifiers()
Expand Down Expand Up @@ -1077,66 +1074,8 @@ public BuilderContext(Elements elements, Types types, Boolean generateBuilderPac

.addNewMethod()
.withNewModifiers().withPublic().endModifiers()
.withName("accept")
.withReturnType(F.toReference())
.addNewArgument()
.withName("visitors")
.withTypeRef(new ClassRefBuilder().withFullyQualifiedName(Visitor.class.getName()).withDimensions(1).build())
.endArgument()
.withVarArgPreferred(true)
.endMethod()

.addNewMethod()
.withNewModifiers().withPublic().endModifiers()
.withName("accept")
.withParameters(V)
.withReturnType(F.toReference())
.addNewArgument()
.withTypeRef(CLASS.toReference(V.toReference()))
.withName("type")
.endArgument()
.addNewArgument()
.withTypeRef(visitorInterface.toReference(V.toReference()))
.withNewModifiers().withFinal().endModifiers()
.withName("visitor")
.endArgument()
.withVarArgPreferred(true)
.endMethod()

.addNewMethod()
.withNewModifiers().withPublic().endModifiers()
.withName("accept")
.withReturnType(F.toReference())
.addNewArgument()
.withName("path")
.withTypeRef(Collections.LIST.toReference(Collections.MAP_ENTRY.toReference(STRING_REF, TypeDef.OBJECT_REF)))
.endArgument()
.addNewArgument()
.withTypeRef(
new ClassRefBuilder().withFullyQualifiedName(visitorInterface.getFullyQualifiedName()).withDimensions(1).build())
.withName("visitors")
.endArgument()
.withVarArgPreferred(true)
.endMethod()

.addNewMethod()
.withNewModifiers().withPublic().endModifiers()
.withName("accept")
.withReturnType(F.toReference())
.addNewArgument()
.withName("path")
.withTypeRef(Collections.LIST.toReference(Collections.MAP_ENTRY.toReference(STRING_REF, TypeDef.OBJECT_REF)))
.endArgument()
.addNewArgument()
.withTypeRef(STRING_REF)
.withName("currentKey")
.endArgument()
.addNewArgument()
.withTypeRef(
new ClassRefBuilder().withFullyQualifiedName(visitorInterface.getFullyQualifiedName()).withDimensions(1).build())
.withName("visitors")
.endArgument()
.withVarArgPreferred(true)
.withName("getVisitableMap")
.withReturnType(OPTIONAL.toReference(visitableMapClass.toReference()))
.endMethod()

.addNewMethod()
Expand Down Expand Up @@ -1274,10 +1213,6 @@ public TypeDef getBaseFluentClass() {
return baseFluentClass;
}

public TypeDef getFluentInterface() {
return fluentInterface;
}

public TypeDef getBuilderInterface() {
return builderInterface;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ void generateLocalDependenciesIfNeeded() {
generate(context.getVisitableBuilderInterface());
generate(context.getVisitableMapClass());
generate(context.getBuilderInterface());
generate(context.getFluentInterface());
generate(context.getBaseFluentClass());
generate(context.getNestedInterface());
generate(context.getEditableInterface());
Expand Down
79 changes: 6 additions & 73 deletions core/src/main/java/io/sundr/builder/BaseFluent.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,16 @@

package io.sundr.builder;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class BaseFluent<F extends Fluent<F>> implements Fluent<F>, Visitable<F> {
public class BaseFluent<F> {

public final VisitableMap _visitables = new VisitableMap();

Expand Down Expand Up @@ -70,75 +68,6 @@ public static <T> Set<T> aggregate(Set<? extends T>... sets) {
return new LinkedHashSet(Arrays.stream(sets).filter(Objects::nonNull).collect(Collectors.toSet()));
}

@Override
public F accept(Visitor... visitors) {
return accept(Collections.emptyList(), visitors);
}

@Override
public <V> F accept(Class<V> type, Visitor<V> visitor) {
return accept(Collections.emptyList(), new Visitor<V>() {
@Override
public Class<V> getType() {
return type;
}

@Override
public void visit(List<Entry<String, Object>> path, V element) {
visitor.visit(path, element);
}

@Override
public void visit(V element) {
visitor.visit(element);
}
});
}

@Override
public F accept(List<Entry<String, Object>> path, String currentKey, Visitor... visitors) {
List<Visitor> sortedVisitor = new ArrayList<>();
for (Visitor visitor : visitors) {
visitor = VisitorListener.wrap(visitor);
if (!visitor.canVisit(path, this)) {
continue;
}
sortedVisitor.add(visitor);
}
sortedVisitor.sort((l, r) -> ((Visitor) r).order() - ((Visitor) l).order());
for (Visitor visitor : sortedVisitor) {
visitor.visit(path, this);
}

List<Entry<String, Object>> copyOfPath = path != null ? new ArrayList(path) : new ArrayList<>();
copyOfPath.add(new AbstractMap.SimpleEntry<>(currentKey, this));

for (Entry<String, ?> entry : _visitables.entrySet()) {
List<Entry<String, Object>> newPath = Collections.unmodifiableList(copyOfPath);

// Copy visitables to avoid ConcurrentModificationException when Visitors add/remove Visitables
for (Visitable<F> visitable : new ArrayList<>((List<Visitable<F>>) entry.getValue())) {
for (Visitor visitor : visitors) {
if (visitor.getType() != null && visitor.getType().isAssignableFrom(visitable.getClass())) {
visitable.accept(newPath, entry.getKey(), visitor);
}
}

for (Visitor visitor : visitors) {
if (visitor.getType() == null || !visitor.getType().isAssignableFrom(visitable.getClass())) {
visitable.accept(newPath, entry.getKey(), visitor);
}
}
}
}
return (F) this;
}

@Override
public F accept(List<Entry<String, Object>> path, Visitor... visitors) {
return accept(path, "", visitors);
}

@Override
public int hashCode() {
final int prime = 31;
Expand All @@ -157,4 +86,8 @@ public boolean equals(Object obj) {
return false;
return true;
}

public Optional<VisitableMap> getVisitableMap() {
return Optional.of(_visitables);
}
}
27 changes: 0 additions & 27 deletions core/src/main/java/io/sundr/builder/Fluent.java

This file was deleted.

69 changes: 54 additions & 15 deletions core/src/main/java/io/sundr/builder/Visitable.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,88 @@

package io.sundr.builder;

import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;

public interface Visitable<T> {

default T accept(Visitor<?>... visitors) {
return accept(Collections.emptyList(), visitors);
}

default <V> T accept(Class<V> type, Visitor<V> visitor) {
return accept(new Visitor<V>() {
return accept(Collections.emptyList(), new Visitor<V>() {
@Override
public Class<V> getType() {
return type;
}

@Override
public void visit(List<Entry<String, Object>> path, V element) {
visitor.visit(path, element);
}

@Override
public void visit(V element) {
visitor.visit(element);
}
});
}

default T accept(Visitor... visitors) {
for (Visitor visitor : visitors) {
if (visitor.canVisit(Collections.emptyList(), this)) {
visitor.visit(this);
}
}
return getTarget(this);
default T accept(List<Entry<String, Object>> path, Visitor<?>... visitors) {
return accept(path, "", visitors);
}

default T accept(List<Entry<String, Object>> path, String currentKey, Visitor... visitors) {
default T accept(List<Entry<String, Object>> path, String currentKey, Visitor<?>... visitors) {
List<Visitor> sortedVisitor = new ArrayList<>();
for (Visitor visitor : visitors) {
if (visitor.canVisit(path, this)) {
visitor.visit(path, this);
visitor = VisitorListener.wrap(visitor);
if (!visitor.canVisit(path, this)) {
continue;
}
sortedVisitor.add(visitor);
}
sortedVisitor.sort((l, r) -> ((Visitor) r).order() - ((Visitor) l).order());
for (Visitor visitor : sortedVisitor) {
visitor.visit(path, this);
}
return getTarget(this);
}

default T accept(List<Entry<String, Object>> path, Visitor... visitors) {
return accept(path, "", visitors);
List<Entry<String, Object>> copyOfPath = path != null ? new ArrayList(path) : new ArrayList<>();
copyOfPath.add(new AbstractMap.SimpleEntry<>(currentKey, this));

getVisitableMap().ifPresent(vm -> {
for (Entry<String, ?> entry : vm.entrySet()) {
List<Entry<String, Object>> newPath = Collections.unmodifiableList(copyOfPath);

// Copy visitables to avoid ConcurrentModificationException when Visitors add/remove Visitables
for (Visitable<T> visitable : new ArrayList<>((List<Visitable<T>>) entry.getValue())) {
for (Visitor visitor : visitors) {
if (visitor.getType() != null && visitor.getType().isAssignableFrom(visitable.getClass())) {
visitable.accept(newPath, entry.getKey(), visitor);
}
}

for (Visitor visitor : visitors) {
if (visitor.getType() == null || !visitor.getType().isAssignableFrom(visitable.getClass())) {
visitable.accept(newPath, entry.getKey(), visitor);
}
}
}
}
});

return (T) this;
}

default T getTarget(Visitable<T> visitable) {
return (T) visitable;
}

default Optional<VisitableMap> getVisitableMap() {
return Optional.empty();
}
}
Loading

0 comments on commit ac109d6

Please sign in to comment.