Skip to content

Commit

Permalink
catch unguessable annotation types
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Hoß committed Jun 26, 2022
1 parent a1a715c commit c774059
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
*/
package wtf.metio.yosql.codegen.blocks;

import ch.qos.cal10n.IMessageConveyor;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import de.xn__ho_hia.javapoet.TypeGuesser;
import wtf.metio.yosql.codegen.orchestration.ExecutionErrors;
import wtf.metio.yosql.models.configuration.Annotation;
import wtf.metio.yosql.models.configuration.AnnotationMember;
import wtf.metio.yosql.models.configuration.GeneratedAnnotationApis;
Expand All @@ -19,8 +21,12 @@
import wtf.metio.yosql.models.immutables.SqlConfiguration;

import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;

import static wtf.metio.yosql.codegen.lifecycle.ApplicationWarnings.CANNOT_GUESS_ANNOTATION_MEMBER_TYPE;
import static wtf.metio.yosql.codegen.lifecycle.ApplicationWarnings.CANNOT_GUESS_ANNOTATION_TYPE;

public final class DefaultAnnotations implements Annotations {

Expand All @@ -39,9 +45,16 @@ public final class DefaultAnnotations implements Annotations {
GeneratedAnnotationMembers.WITHOUT_DATE);

private final AnnotationsConfiguration annotations;
private final ExecutionErrors errors;
private final IMessageConveyor messages;

public DefaultAnnotations(final AnnotationsConfiguration annotations) {
public DefaultAnnotations(
final AnnotationsConfiguration annotations,
final ExecutionErrors errors,
final IMessageConveyor messages) {
this.annotations = annotations;
this.errors = errors;
this.messages = messages;
}

@Override
Expand Down Expand Up @@ -88,52 +101,62 @@ private Iterable<AnnotationSpec> getAnnotationSpecs(
if (OPTIONS_WITH_COMMENT.contains(memberOption)) {
builder.addMember("comments", "$S", comment);
}
return Collections.singletonList(builder.build());
return List.of(builder.build());
}
return Collections.emptyList();
return List.of();
}

@Override
public Iterable<AnnotationSpec> generatedRepository() {
return annotations.repositoryAnnotations().stream()
.map(DefaultAnnotations::asAnnotationSpec)
.flatMap(annotation -> asAnnotationSpec(annotation).stream())
.toList();
}

@Override
public Iterable<AnnotationSpec> generatedMethod(final SqlConfiguration configuration) {
return Annotation.mergeAnnotations(configuration.annotations(), annotations.methodAnnotations()).stream()
.map(DefaultAnnotations::asAnnotationSpec)
.flatMap(annotation -> asAnnotationSpec(annotation).stream())
.toList();
}

@Override
public Iterable<AnnotationSpec> generatedConstructor() {
return annotations.constructorAnnotations().stream()
.map(DefaultAnnotations::asAnnotationSpec)
.flatMap(annotation -> asAnnotationSpec(annotation).stream())
.toList();
}

// visible for testing
static AnnotationSpec asAnnotationSpec(final Annotation annotation) {
// TODO: catch exception thrown by bestGuess and return Optional + use ExecutionErrors?
final var type = ClassName.bestGuess(annotation.type());
final var builder = AnnotationSpec.builder(type);
annotation.members().forEach(member -> builder.addMember(member.key(), asAnnotationMemberSpec(member)));
return builder.build();
Optional<AnnotationSpec> asAnnotationSpec(final Annotation annotation) {
try {
final var type = ClassName.bestGuess(annotation.type());
final var builder = AnnotationSpec.builder(type);
annotation.members().forEach(member -> asAnnotationMemberSpec(member)
.ifPresent(code -> builder.addMember(member.key(), code)));
return Optional.of(builder.build());
} catch (final IllegalArgumentException exception) {
errors.illegalArgument(exception, messages.getMessage(CANNOT_GUESS_ANNOTATION_TYPE, annotation.type()));
return Optional.empty();
}
}

private static CodeBlock asAnnotationMemberSpec(final AnnotationMember member) {
final var builder = CodeBlock.builder();
final var type = TypeGuesser.guessTypeName(member.type());
if (TypeName.CHAR.equals(type)) {
builder.add("'$L'", member.value());
} else if (type.isPrimitive()) {
builder.add("$L", member.value());
} else {
builder.add("$S", member.value());
private Optional<CodeBlock> asAnnotationMemberSpec(final AnnotationMember member) {
try {
final var builder = CodeBlock.builder();
final var type = TypeGuesser.guessTypeName(member.type());
if (TypeName.CHAR.equals(type)) {
builder.add("'$L'", member.value());
} else if (type.isPrimitive()) {
builder.add("$L", member.value());
} else {
builder.add("$S", member.value());
}
return Optional.of(builder.build());
} catch (final IllegalArgumentException exception) {
errors.illegalArgument(exception, messages.getMessage(CANNOT_GUESS_ANNOTATION_MEMBER_TYPE, member.type()));
return Optional.empty();
}
return builder.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public ToMapConverterGenerator(
public PackagedTypeSpec generateToMapConverterClass() {
final var mapConverterClass = ClassName.bestGuess(converters.mapConverterClass());
final var type = classes.publicClass(mapConverterClass)
// TODO: add javadoc with hint to disable generating this class
.addJavadoc("Disable generating this class by setting 'generateMapConverter' to 'false'.")
.addAnnotations(annotations.generatedClass())
.addMethod(toMapMethod())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,14 @@ public enum ApplicationWarnings {
*/
SQL_STATEMENT_IGNORED,

/**
* Signals that an annotation type cannot be guessed.
*/
CANNOT_GUESS_ANNOTATION_TYPE,

/**
* Signals that an annotation type cannot be guessed.
*/
CANNOT_GUESS_ANNOTATION_MEMBER_TYPE,

}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ public void illegalArgument(final String message, final Object... arguments) {
errors.add(new IllegalArgumentException(String.format(message, arguments)));
}

/**
* @param cause The root cause of the illegal argument.
* @param message The message to include.
* @param arguments The arguments to apply to the message.
*/
public void illegalArgument(final Exception cause, final String message, final Object... arguments) {
errors.add(new IllegalArgumentException(String.format(message, arguments), cause));
}

/**
* @param message The message to include.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
# in the LICENSE file.
#
SQL_STATEMENT_IGNORED=[WARNUNG] Statement [{0}] aus [{1}] ignoriert
CANNOT_GUESS_ANNOTATION_TYPE=[WARN] Annotation Type [{0}] kann nicht erraten werden
CANNOT_GUESS_ANNOTATION_MEMBER_TYPE=[WARN] Annotation Member Type [{0}] kann nicht erraten werden
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
# in the LICENSE file.
#
SQL_STATEMENT_IGNORED=[WARN] ignored statement [{0}] from [{1}]
CANNOT_GUESS_ANNOTATION_TYPE=[WARN] cannot guess annotation type from [{0}]
CANNOT_GUESS_ANNOTATION_MEMBER_TYPE=[WARN] cannot guess annotation member type from [{0}]
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

package wtf.metio.yosql.codegen.blocks;

import ch.qos.cal10n.MessageConveyor;
import wtf.metio.yosql.internals.jdk.SupportedLocales;
import wtf.metio.yosql.codegen.logging.LoggingObjectMother;
import wtf.metio.yosql.codegen.orchestration.OrchestrationObjectMother;
import wtf.metio.yosql.internals.testing.configs.AnnotationsConfigurations;
import wtf.metio.yosql.internals.testing.configs.FilesConfigurations;
import wtf.metio.yosql.internals.testing.configs.JavaConfigurations;
Expand Down Expand Up @@ -58,15 +58,18 @@ public static ControlFlows controlFlows(final JavaConfiguration java) {
}

public static Annotations annotationGenerator() {
return new DefaultAnnotations(AnnotationsConfigurations.defaults());
return new DefaultAnnotations(
AnnotationsConfigurations.defaults(),
OrchestrationObjectMother.executionErrors(),
LoggingObjectMother.messages());
}

public static Javadoc javadoc() {
return javadoc(FilesConfigurations.maven());
}

public static Javadoc javadoc(final FilesConfiguration files) {
return new DefaultJavadoc(files, new MessageConveyor(SupportedLocales.ENGLISH));
return new DefaultJavadoc(files, LoggingObjectMother.messages());
}

private BlocksObjectMother() {
Expand Down
Loading

0 comments on commit c774059

Please sign in to comment.