use of io.sundr.model.Method in project sundrio by sundrio.
the class AbstractBuilderProcessor method inlineableOf.
static TypeDef inlineableOf(BuilderContext ctx, TypeDef type, Inline inline) {
final String inlineableName = !inline.name().isEmpty() ? inline.name() : inline.prefix() + type.getName() + inline.suffix();
List<Method> constructors = new ArrayList<Method>();
final TypeDef builderType = TypeAs.BUILDER.apply(type);
TypeDef inlineType = BuilderUtils.getInlineType(ctx, inline);
TypeDef returnType = BuilderUtils.getInlineReturnType(ctx, inline, type);
final ClassRef inlineTypeRef = inlineType.toReference(returnType.toReference());
// Use the builder as the base of the inlineable. Just add interface and change name.
final TypeDef shallowInlineType = new TypeDefBuilder(builderType).withName(inlineableName).withImplementsList(inlineTypeRef).withProperties().withMethods().withConstructors().build();
TypeRef functionType = Constants.FUNCTION.toReference(type.toInternalReference(), returnType.toInternalReference());
Property builderProperty = new PropertyBuilder().withTypeRef(TypeAs.BUILDER.apply(type).toInternalReference()).withName(BUILDER).withModifiers(Types.modifiersToInt(Modifier.PRIVATE, Modifier.FINAL)).build();
Property functionProperty = new PropertyBuilder().withTypeRef(functionType).withName(FUNCTION).withModifiers(Types.modifiersToInt(Modifier.PRIVATE, Modifier.FINAL)).build();
Method inlineMethod = new MethodBuilder().withReturnType(returnType.toInternalReference()).withName(inline.value()).withNewBlock().addNewStringStatementStatement(BUILD_AND_APPLY_FUNCTION).endBlock().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).build();
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(FUNCTION).withTypeRef(functionType).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BULDER_AND_SET_FUNCTION_FORMAT, builderType.getName())).endBlock().build());
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(ITEM).withTypeRef(type.toInternalReference()).and().addNewArgument().withName(FUNCTION).withTypeRef(functionType).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BULDER_WITH_ITEM_AND_SET_FUNCTION_FORMAT, builderType.getName())).endBlock().build());
if (type.equals(returnType)) {
constructors.add(new MethodBuilder().withReturnType(inlineTypeRef).withName(EMPTY).addNewArgument().withName(ITEM).withTypeRef(type.toInternalReference()).and().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withNewBlock().addNewStringStatementStatement(String.format(NEW_BUILDER_AND_EMTPY_FUNCTION_FORMAT, builderType.getName(), String.format(EMPTY_FUNCTION_TEXT, type.toInternalReference(), returnType.toInternalReference(), returnType.toInternalReference(), type.toInternalReference()))).endBlock().build());
}
return new TypeDefBuilder(shallowInlineType).withAnnotations().withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withConstructors(constructors).addToProperties(builderProperty, functionProperty).addToMethods(inlineMethod).accept(new TypedVisitor<ClassRefBuilder>() {
@Override
public void visit(ClassRefBuilder builder) {
List<TypeRef> updatedArguments = new ArrayList<TypeRef>();
for (TypeRef arg : builder.getArguments()) {
if (arg.equals(builderType.toInternalReference())) {
updatedArguments.add(shallowInlineType.toInternalReference());
} else {
updatedArguments.add(arg);
}
}
builder.withArguments(updatedArguments);
}
}).build();
}
use of io.sundr.model.Method in project sundrio by sundrio.
the class TypeDefUtils method executableToInterface.
/**
* Convert an {@link javax.lang.model.element.ExecutableElement} to a {@link io.sundr.model.TypeDef}
*
* @param context The context of the operation.
* @param executableElement The target element.
* @return An instance of {@link io.sundr.model.TypeDef} that describes the interface.
*/
public static TypeDef executableToInterface(DslContext context, ExecutableElement executableElement) {
// Do generate the interface
Boolean multiple = executableElement.getAnnotation(Multiple.class) != null;
Boolean isEntryPoint = executableElement.getAnnotation(EntryPoint.class) != null;
Boolean isTerminal = executableElement.getAnnotation(Terminal.class) != null || !isVoid(executableElement);
Set<String> classes = new HashSet<String>();
Set<String> keywords = new HashSet<String>();
Set<String> methods = new HashSet<String>();
TransitionFilter filter = executableElement.getAnnotation(Or.class) != null ? new OrTransitionFilter(context.getToRequiresAll().apply(executableElement), context.getToRequiresAny().apply(executableElement), context.getToRequiresOnly().apply(executableElement), context.getToRequiresNoneOf().apply(executableElement)) : new AndTransitionFilter(context.getToRequiresAll().apply(executableElement), context.getToRequiresAny().apply(executableElement), context.getToRequiresOnly().apply(executableElement), context.getToRequiresNoneOf().apply(executableElement));
for (String clazz : context.getToClasses().apply(executableElement)) {
classes.add(clazz);
}
for (String keyword : context.getToKeywords().apply(executableElement)) {
keywords.add(keyword);
}
// Let's add the name of the method as a keyword to make things simpler
methods.add(executableElement.getSimpleName().toString());
TypeRef returnType;
if (isTerminal(executableElement)) {
returnType = isVoid(executableElement) ? VOID_REF : Adapters.adaptReference(executableElement.getReturnType(), context.getAptContext());
} else {
returnType = TRANSPARENT_REF;
}
InterfaceName targetInterfaceName = executableElement.getAnnotation(InterfaceName.class);
MethodName tagetMethodName = executableElement.getAnnotation(MethodName.class);
Begin begin = executableElement.getAnnotation(Begin.class);
End end = executableElement.getAnnotation(End.class);
if (begin != null) {
keywords.add(begin.value());
}
if (end != null) {
keywords.add(end.value());
}
String methodName = tagetMethodName != null ? tagetMethodName.value() : executableElement.getSimpleName().toString();
String beginScope = begin != null ? begin.value() : null;
String endScope = end != null ? end.value() : null;
TypeParamDef paremeterType = Generics.MAP.apply(returnType);
Method sourceMethod = Adapters.adaptMethod(executableElement, context.getAptContext());
List<AnnotationRef> annotations = new ArrayList<AnnotationRef>();
for (AnnotationRef candidate : sourceMethod.getAnnotations()) {
if (!candidate.getClassRef().getFullyQualifiedName().startsWith("io.sundr")) {
annotations.add(candidate);
}
}
Method targetMethod = new MethodBuilder(sourceMethod).withAnnotations(annotations).withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).withReturnType(paremeterType.toReference()).withName(methodName).build();
String interfaceName = targetInterfaceName != null ? targetInterfaceName.value() : toInterfaceName(targetMethod.getName());
return new TypeDefBuilder().withPackageName(Apt.getPackageElement(executableElement).toString()).withName(interfaceName).withParameters(paremeterType).withKind(Kind.INTERFACE).withModifiers(Types.modifiersToInt(Modifier.PUBLIC)).addToAttributes(ORIGINAL_RETURN_TYPE, returnType).addToAttributes(IS_ENTRYPOINT, isEntryPoint).addToAttributes(IS_TERMINAL, isTerminal).addToAttributes(IS_GENERIC, Boolean.FALSE).addToAttributes(CLASSES, classes).addToAttributes(KEYWORDS, keywords).addToAttributes(METHODS, methods).addToAttributes(BEGIN_SCOPE, beginScope).addToAttributes(END_SCOPE, endScope).addToAttributes(FILTER, filter).addToAttributes(CARDINALITY_MULTIPLE, multiple).addToAttributes(METHOD_NAME, methodName).addToMethods(targetMethod).build();
}
use of io.sundr.model.Method in project sundrio by sundrio.
the class ClazzAs method staticAdapterBody.
private static String staticAdapterBody(TypeDef pojo, TypeDef pojoBuilder, TypeDef source, boolean returnBuilder) {
StringBuilder sb = new StringBuilder();
sb.append("return new ").append(pojoBuilder.getName()).append("()");
for (Method m : source.getMethods()) {
String trimmedName = Strings.deCapitalizeFirst(m.getName().replaceAll("^get", "").replaceAll("^is", ""));
if (m.getReturnType() instanceof ClassRef) {
ClassRef ref = (ClassRef) m.getReturnType();
Boolean hasSuperClass = pojo.getProperties().stream().filter(p -> p.getTypeRef() instanceof ClassRef && p.getName().equals(Getter.propertyNameSafe(m))).map(p -> GetDefinition.of((ClassRef) p.getTypeRef())).flatMap(c -> c.getExtendsList().stream()).count() > 0;
if (GetDefinition.of(ref).isAnnotation()) {
TypeDef generatedType = Types.allProperties(pojo).stream().filter(p -> p.getName().equals(m.getName())).map(p -> p.getTypeRef()).filter(r -> r instanceof ClassRef).map(r -> (ClassRef) r).map(c -> GetDefinition.of(c)).findFirst().orElse(null);
if (generatedType != null) {
Method ctor = BuilderUtils.findBuildableConstructor(generatedType);
if (m.getReturnType().getDimensions() > 0) {
sb.append(".addAllTo").append(Strings.capitalizeFirst(trimmedName)).append("(").append("Arrays.asList(").append("instance.").append(m.getName()).append("())").append(".stream().map(i ->").append("new ").append(generatedType.getName()).append("(").append(ctor.getArguments().stream().map(p -> Getter.find(GetDefinition.of((ClassRef) m.getReturnType()), p, true)).map(g -> g.getName()).map(s -> "i." + s + "()").collect(Collectors.joining(", "))).append(")").append(")").append(".collect(Collectors.toList()))");
} else {
sb.append(".with").append(Strings.capitalizeFirst(trimmedName)).append("(").append("new ").append(generatedType.getName()).append("(").append(ctor.getArguments().stream().map(p -> Getter.find(GetDefinition.of((ClassRef) m.getReturnType()), p, true)).map(g -> g.getName()).map(s -> "instance." + m.getName() + "()." + s + "()").collect(Collectors.joining(", "))).append(")").append(")");
}
continue;
}
}
}
String withMethod = "with" + (Strings.capitalizeFirst(trimmedName));
if (Types.hasProperty(pojo, trimmedName)) {
sb.append(".").append(withMethod).append("(").append("instance.").append(m.getName()).append("())");
}
}
if (returnBuilder) {
sb.append(".build();");
} else {
sb.append(";");
}
return sb.toString();
}
use of io.sundr.model.Method in project sundrio by sundrio.
the class ClazzAs method toInstanceConstructorBody.
private static List<Statement> toInstanceConstructorBody(TypeDef clazz, TypeDef instance, String fluent) {
Method constructor = findBuildableConstructor(clazz);
List<Statement> statements = new ArrayList<Statement>();
final String ref = fluent != null && !fluent.isEmpty() ? fluent : "this";
// We may use a reference to fluent or we may use directly "this". So we need to check.
if (fluent != null && !fluent.isEmpty()) {
statements.add(new StringStatement("this.fluent = " + fluent + "; "));
}
for (Property property : constructor.getArguments()) {
Optional<Method> getter = Getter.findOptional(instance, property);
getter.ifPresent(g -> {
String cast = property.getTypeRef() instanceof TypeParamRef ? "(" + property.getTypeRef().toString() + ")" : "";
statements.add(new StringStatement(new StringBuilder().append(ref).append(".with").append(property.getNameCapitalized()).append("(").append(cast).append("instance.").append(g.getName()).append("()); ").toString()));
});
// } else {
// throw new IllegalStateException("Could not find getter for property:" + property + " in class:" + clazz);
// }
}
TypeDef target = clazz;
// Iterate parent objects and check for properties with setters but not ctor arguments.
while (target != null && !Types.OBJECT.equals(target) && BuilderUtils.isBuildable(target)) {
for (Property property : target.getProperties()) {
if (!hasBuildableConstructorWithArgument(target, property) && Setter.has(target, property)) {
Getter.findOptional(instance, property).map(Method::getName).ifPresent(getterName -> {
String withName = "with" + property.getNameCapitalized();
statements.add(new StringStatement(new StringBuilder().append(ref).append(".").append(withName).append("(instance.").append(getterName).append("());\n").toString()));
});
}
}
if (!target.getExtendsList().isEmpty()) {
target = BuilderContextManager.getContext().getBuildableRepository().getBuildable(target.getExtendsList().iterator().next());
} else {
return statements;
}
}
return statements;
}
use of io.sundr.model.Method in project sundrio by sundrio.
the class BindDefinitionTest method shouldTranslateMethod.
@Test
public void shouldTranslateMethod() {
ClassRef string = ClassRef.forName(String.class.getName());
TypeDef bound = BindDefinition.of(target.toReference(string));
assertNotNull(bound);
assertTrue(bound.getParameters().isEmpty());
Optional<Method> getType = bound.getMethods().stream().filter(p -> "getType".equals(p.getName())).findFirst();
assertTrue(getType.isPresent());
getType.ifPresent(p -> {
assertEquals(string, p.getReturnType());
});
}
Aggregations