Skip to content

Commit

Permalink
Documented the views of codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
Pyknic committed Aug 6, 2015
1 parent 7985442 commit 12c95b3
Show file tree
Hide file tree
Showing 47 changed files with 812 additions and 312 deletions.
5 changes: 5 additions & 0 deletions src/main/java/com/speedment/codegen/base/Transform.java
Expand Up @@ -33,6 +33,11 @@ public interface Transform<F, T> {
* code generator is supplied so that intermediate generation processes can * code generator is supplied so that intermediate generation processes can
* be initiated to resolve dependencies. The transform can choose not to * be initiated to resolve dependencies. The transform can choose not to
* accept a particular input and therefore return <code>empty</code>. * accept a particular input and therefore return <code>empty</code>.
* <p>
* This method is not meant to be called outside the code generator. If you
* want to transform between different types, setup a {@see Generator},
* install the <code>Transform</code> in the factory and call one of the
* <code>on()<code>-methods in <code>Generator</code>.
* *
* @param gen a reference to the generator being used * @param gen a reference to the generator being used
* @param model the model to transform * @param model the model to transform
Expand Down
Expand Up @@ -25,23 +25,28 @@
import java.util.stream.Stream; import java.util.stream.Stream;


/** /**
* * Transforms from an {@link AnnotationUsage} to java code.
*
* @author Emil Forslund * @author Emil Forslund
*/ */
public class AnnotationUsageView implements Transform<AnnotationUsage, String> { public class AnnotationUsageView implements Transform<AnnotationUsage, String> {

private final static String private final static String
PSTART = "(", PSTART = "(",
EQUALS = " = "; EQUALS = " = ";


/**
* {@inheritDoc}
*/
@Override @Override
public Optional<String> transform(Generator cg, AnnotationUsage model) { public Optional<String> transform(Generator gen, AnnotationUsage model) {
final Optional<String> value = cg.on(model.getValue()); final Optional<String> value = gen.on(model.getValue());
final Stream<String> valueStream = value.isPresent() ? Stream.of(value.get()) : Stream.empty(); final Stream<String> valueStream = value.isPresent() ? Stream.of(value.get()) : Stream.empty();


return Optional.of( return Optional.of(
AT + cg.on(model.getType()).get() + AT + gen.on(model.getType()).get() +
Stream.of( Stream.of(
model.getValues().stream().map(e -> e.getKey() + cg.on(e.getValue()).map(s -> EQUALS + s).orElse(EMPTY)), model.getValues().stream().map(e -> e.getKey() + gen.on(e.getValue()).map(s -> EQUALS + s).orElse(EMPTY)),
valueStream valueStream
).flatMap(s -> s).collect( ).flatMap(s -> s).collect(
CodeCombiner.joinIfNotEmpty( CodeCombiner.joinIfNotEmpty(
Expand Down
23 changes: 14 additions & 9 deletions src/main/java/com/speedment/codegen/java/views/AnnotationView.java
Expand Up @@ -27,33 +27,38 @@
import com.speedment.codegen.util.CodeCombiner; import com.speedment.codegen.util.CodeCombiner;


/** /**
* * Transforms from an {@link Annotation} to java code.
*
* @author Emil Forslund * @author Emil Forslund
*/ */
public class AnnotationView implements Transform<Annotation, String>, public class AnnotationView implements Transform<Annotation, String>,
HasJavadocView<Annotation>, HasAnnotationUsageView<Annotation>, HasNameView<Annotation> { HasJavadocView<Annotation>, HasAnnotationUsageView<Annotation>,
HasNameView<Annotation> {


private final static String private final static String
INTERFACE_STRING = "@interface ", INTERFACE_STRING = "@interface ",
DEFAULT_STRING = " default "; DEFAULT_STRING = " default ";


/**
* {@inheritDoc}
*/
@Override @Override
public Optional<String> transform(Generator cg, Annotation model) { public Optional<String> transform(Generator gen, Annotation model) {
return Optional.of( return Optional.of(
renderAnnotations(cg, model) + renderAnnotations(gen, model) +
renderAnnotations(cg, model) + renderAnnotations(gen, model) +
INTERFACE_STRING + INTERFACE_STRING +
renderName(cg, model) + renderName(gen, model) +
block( block(
model.getFields().stream().map(f -> model.getFields().stream().map(f ->
// Field javadoc (optional) // Field javadoc (optional)
ifelse(cg.on(f.getJavadoc()), jd -> nl() + jd + nl(), EMPTY) + ifelse(gen.on(f.getJavadoc()), jd -> nl() + jd + nl(), EMPTY) +


// Field declaration // Field declaration
cg.on(f.getType()) + SPACE + f.getName() + PS + PE + gen.on(f.getType()) + SPACE + f.getName() + PS + PE +


// Default value (optional) // Default value (optional)
ifelse(cg.on(f.getValue()), v -> (DEFAULT_STRING + v), EMPTY) + ifelse(gen.on(f.getValue()), v -> (DEFAULT_STRING + v), EMPTY) +


SC SC
).collect(CodeCombiner.joinIfNotEmpty(nl())) ).collect(CodeCombiner.joinIfNotEmpty(nl()))
Expand Down
Expand Up @@ -30,18 +30,18 @@
import com.speedment.codegen.java.views.interfaces.HasModifiersView; import com.speedment.codegen.java.views.interfaces.HasModifiersView;
import com.speedment.codegen.java.views.interfaces.HasNameView; import com.speedment.codegen.java.views.interfaces.HasNameView;
import com.speedment.codegen.lang.models.ClassOrInterface; import com.speedment.codegen.lang.models.ClassOrInterface;
import com.speedment.codegen.lang.models.Field;
import java.util.Optional; import java.util.Optional;
import java.util.Collection; import static java.util.stream.Collectors.joining;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;




/** /**
* * An abstract base class used to share functionality between different view
* components such as {@link ClassView}, {@link EnumView} and
* {@link InterfaceView}.
*
* @param <M> The extending model type
* @author Emil Forslund * @author Emil Forslund
* @param <M> The extending type
*/ */
public abstract class ClassOrInterfaceView<M extends ClassOrInterface<M>> implements public abstract class ClassOrInterfaceView<M extends ClassOrInterface<M>> implements
Transform<M, String>, HasNameView<M>, HasModifiersView<M>, HasJavadocView<M>, Transform<M, String>, HasNameView<M>, HasModifiersView<M>, HasJavadocView<M>,
Expand All @@ -55,61 +55,99 @@ public abstract class ClassOrInterfaceView<M extends ClassOrInterface<M>> implem
IMPLEMENTS_STRING = "implements ", IMPLEMENTS_STRING = "implements ",
EXTENDS_STRING = "extends "; EXTENDS_STRING = "extends ";


protected String onBeforeFields(Generator cg, M model) { /**
* A hook that is executed just before the 'fields' part of the class code.
*
* @param gen the generator being used
* @param model the model that is generated
* @return code to be inserted before the fields
*/
protected String onBeforeFields(Generator gen, M model) {
return EMPTY; return EMPTY;
} }

protected Object wrapField(Field field) {return field;}

@Override
public <In, C extends Collection<In>> Collection<Object>
wrap(C models, Function<In, Object> wrapper) {
return models.stream().map(wrapper).collect(Collectors.toList());
}


/**
* {@inheritDoc}
*/
@Override @Override
public String fieldSeparator() { public String fieldSeparator() {
return nl(); return nl();
} }


/**
* {@inheritDoc}
*/
@Override @Override
public String fieldSuffix() { public String fieldSuffix() {
return SC; return SC;
} }


/**
* Returns the declaration type of this model. This can be either 'class',
* 'interface' or 'enum'.
*
* @return the declaration type
*/
protected abstract String renderDeclarationType(); protected abstract String renderDeclarationType();
protected abstract String renderSupertype(Generator cg, M model);
protected abstract String renderConstructors(Generator cg, M model);


/**
* Returns the supertype of this model. The supertype should include any
* declaration like 'implements' or 'extends'.
* <p>
* Example: <pre>"implements List<T>"</pre>
*
* @return the supertype part
*/
protected abstract String renderSupertype(Generator gen, M model);

/**
* Should render the constructors part of the code and return it.
*
* @param gen the generator to use
* @param model the model of the component
* @return generated constructors or an empty string if there shouldn't
* be any
*/
protected abstract String renderConstructors(Generator gen, M model);

/**
* {@inheritDoc}
*/
@Override @Override
public Optional<String> transform(Generator cg, M model) { public Optional<String> transform(Generator gen, M model) {
return Optional.of(renderJavadoc(cg, model) + return Optional.of(renderJavadoc(gen, model) +
renderAnnotations(cg, model) + renderAnnotations(gen, model) +
renderModifiers(cg, model) + renderModifiers(gen, model) +
renderDeclarationType() + renderDeclarationType() +
renderName(cg, model) + renderName(gen, model) +
renderGenerics(cg, model) + renderGenerics(gen, model) +
renderSupertype(cg, model) + renderSupertype(gen, model) +
renderInterfaces(cg, model) + renderInterfaces(gen, model) +


// Code // Code
block(nl() + separate( block(nl() + separate(
onBeforeFields(cg, model), // Enums have constants here. onBeforeFields(gen, model), // Enums have constants here.´
// cg.onEach(wrap(model.getFields(), f -> wrapField(f))) renderFields(gen, model),
// .collect(joinIfNotEmpty(scnl(), EMPTY, SC)), renderConstructors(gen, model),
renderFields(cg, model), renderInitalizers(gen, model),
renderConstructors(cg, model), renderMethods(gen, model),
renderInitalizers(cg, model), renderClasses(gen, model)
renderMethods(cg, model),
renderClasses(cg, model)
)) ))
); );
} }


/**
* Converts the specified elements into strings using their
* <code>toString</code>-method and combines them with two new-line-characters.
* Empty strings will be discarded.
*
* @param strings the strings to combine
* @return the combined string
*/
private String separate(Object... strings) { private String separate(Object... strings) {
return Stream.of(strings) return Stream.of(strings)
.map(o -> o.toString()) .map(o -> o.toString())
.filter(s -> s.length() > 0) .filter(s -> s.length() > 0)
.collect(Collectors.joining(dnl())); .collect(joining(dnl()));
} }
} }
23 changes: 18 additions & 5 deletions src/main/java/com/speedment/codegen/java/views/ClassView.java
Expand Up @@ -22,33 +22,46 @@
import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.joining;


/** /**
* * Transforms from a {@link Class} to java code.
*
* @author Emil Forslund * @author Emil Forslund
*/ */
public class ClassView extends ClassOrInterfaceView<Class> { public class ClassView extends ClassOrInterfaceView<Class> {


/**
* {@inheritDoc}
*/
@Override @Override
protected String renderDeclarationType() { protected String renderDeclarationType() {
return CLASS_STRING; return CLASS_STRING;
} }


/**
* {@inheritDoc}
*/
@Override @Override
public String extendsOrImplementsInterfaces() { public String extendsOrImplementsInterfaces() {
return IMPLEMENTS_STRING; return IMPLEMENTS_STRING;
} }


/**
* {@inheritDoc}
*/
@Override @Override
protected String renderSupertype(Generator cg, Class model) { protected String renderSupertype(Generator gen, Class model) {
if (model.getSupertype().isPresent()) { if (model.getSupertype().isPresent()) {
return EXTENDS_STRING + cg.on(model.getSupertype().get()).orElse(EMPTY) + SPACE; return EXTENDS_STRING + gen.on(model.getSupertype().get()).orElse(EMPTY) + SPACE;
} else { } else {
return EMPTY; return EMPTY;
} }
} }


/**
* {@inheritDoc}
*/
@Override @Override
protected String renderConstructors(Generator cg, Class model) { protected String renderConstructors(Generator gen, Class model) {
return cg.onEach(model.getConstructors()) return gen.onEach(model.getConstructors())
.collect(joining(dnl())); .collect(joining(dnl()));
} }
} }
40 changes: 28 additions & 12 deletions src/main/java/com/speedment/codegen/java/views/ConstructorView.java
Expand Up @@ -16,34 +16,41 @@
*/ */
package com.speedment.codegen.java.views; package com.speedment.codegen.java.views;


import com.speedment.codegen.util.CodeCombiner;
import static com.speedment.codegen.util.Formatting.*; import static com.speedment.codegen.util.Formatting.*;
import com.speedment.codegen.base.Generator; import com.speedment.codegen.base.Generator;
import com.speedment.codegen.base.Transform; import com.speedment.codegen.base.Transform;
import com.speedment.codegen.lang.interfaces.HasName; import com.speedment.codegen.lang.interfaces.HasName;
import com.speedment.codegen.lang.models.Constructor; import com.speedment.codegen.lang.models.Constructor;
import static com.speedment.codegen.util.CodeCombiner.joinIfNotEmpty;
import com.speedment.codegen.util.Formatting;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;


/** /**
* * Transforms from a {@link Constructor} to java code.
*
* @author Emil Forslund * @author Emil Forslund
*/ */
public class ConstructorView implements Transform<Constructor, String> { public class ConstructorView implements Transform<Constructor, String> {


private final static String THROWS = "throws "; private final static String THROWS = "throws ";


/**
* {@inheritDoc}
*/
@Override @Override
public Optional<String> transform(Generator cg, Constructor model) { public Optional<String> transform(Generator gen, Constructor model) {
return Optional.of( return Optional.of(
ifelse(cg.on(model.getJavadoc()), s -> s + nl(), EMPTY) + ifelse(gen.on(model.getJavadoc()), s -> s + nl(), EMPTY) +
cg.onEach(model.getModifiers()).collect(CodeCombiner.joinIfNotEmpty(SPACE, EMPTY, SPACE)) + gen.onEach(model.getModifiers()).collect(joinIfNotEmpty(SPACE, EMPTY, SPACE)) +
renderName(cg, model) renderName(gen, model)
.orElseThrow(() -> new UnsupportedOperationException("Could not find a nameable parent of constructor.")) + .orElseThrow(() -> new UnsupportedOperationException(
cg.onEach(model.getFields()).collect( "Could not find a nameable parent of constructor."
)) +
gen.onEach(model.getFields()).collect(
Collectors.joining(COMMA_SPACE, PS, PE) Collectors.joining(COMMA_SPACE, PS, PE)
) + SPACE + ) + SPACE +
cg.onEach(model.getExceptions()).collect(CodeCombiner.joinIfNotEmpty(COMMA_SPACE, THROWS, SPACE)) + gen.onEach(model.getExceptions()).collect(joinIfNotEmpty(COMMA_SPACE, THROWS, SPACE)) +
block( block(
model.getCode().stream().collect( model.getCode().stream().collect(
Collectors.joining(nl()) Collectors.joining(nl())
Expand All @@ -52,11 +59,20 @@ public Optional<String> transform(Generator cg, Constructor model) {
); );
} }


private static Optional<String> renderName(Generator cg, Constructor model) { /**
Optional<String> result = cg.getRenderStack() * Renders the name of this constructor. In java, this is the name of the
* class or enum that the constructor is in.
*
* @param gen the generator
* @param model the constructor
* @return the rendered name
*/
private static Optional<String> renderName(Generator gen, Constructor model) {
Optional<String> result = gen.getRenderStack()
.fromTop(HasName.class) .fromTop(HasName.class)
.filter(n -> model != n) .filter(n -> model != n)
.map(n -> shortName(n.getName())) .map(HasName::getName)
.map(Formatting::shortName)
.findFirst(); .findFirst();


return result; return result;
Expand Down

0 comments on commit 12c95b3

Please sign in to comment.