Search in sources :

Example 11 with Method

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();
}
Also used : TypedVisitor(io.sundr.builder.TypedVisitor) ClassRef(io.sundr.model.ClassRef) TypeRef(io.sundr.model.TypeRef) ClassRefBuilder(io.sundr.model.ClassRefBuilder) ArrayList(java.util.ArrayList) Method(io.sundr.model.Method) TypeDefBuilder(io.sundr.model.TypeDefBuilder) MethodBuilder(io.sundr.model.MethodBuilder) RichTypeDef(io.sundr.model.RichTypeDef) TypeDef(io.sundr.model.TypeDef) Property(io.sundr.model.Property) PropertyBuilder(io.sundr.model.PropertyBuilder)

Example 12 with Method

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();
}
Also used : AndTransitionFilter(io.sundr.dsl.internal.element.functions.filter.AndTransitionFilter) TypeParamDef(io.sundr.model.TypeParamDef) Multiple(io.sundr.dsl.annotations.Multiple) TypeRef(io.sundr.model.TypeRef) ArrayList(java.util.ArrayList) EntryPoint(io.sundr.dsl.annotations.EntryPoint) Method(io.sundr.model.Method) TypeDefBuilder(io.sundr.model.TypeDefBuilder) MethodBuilder(io.sundr.model.MethodBuilder) OrTransitionFilter(io.sundr.dsl.internal.element.functions.filter.OrTransitionFilter) AndTransitionFilter(io.sundr.dsl.internal.element.functions.filter.AndTransitionFilter) TransitionFilter(io.sundr.dsl.internal.element.functions.filter.TransitionFilter) OrTransitionFilter(io.sundr.dsl.internal.element.functions.filter.OrTransitionFilter) Begin(io.sundr.dsl.annotations.Begin) InterfaceName(io.sundr.dsl.annotations.InterfaceName) End(io.sundr.dsl.annotations.End) MethodName(io.sundr.dsl.annotations.MethodName) AnnotationRef(io.sundr.model.AnnotationRef) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 13 with Method

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();
}
Also used : FunctionFactory(io.sundr.FunctionFactory) StringStatement(io.sundr.model.StringStatement) Modifier(javax.lang.model.element.Modifier) Buildable(io.sundr.builder.annotations.Buildable) TypeParamRef(io.sundr.model.TypeParamRef) GetDefinition(io.sundr.model.functions.GetDefinition) TypeDefBuilder(io.sundr.model.TypeDefBuilder) Function(java.util.function.Function) Supplier(java.util.function.Supplier) BuilderUtils(io.sundr.builder.internal.utils.BuilderUtils) ArrayList(java.util.ArrayList) ClassRef(io.sundr.model.ClassRef) Getter(io.sundr.model.utils.Getter) InitEnricher(io.sundr.builder.internal.visitors.InitEnricher) Map(java.util.Map) RichTypeDef(io.sundr.model.RichTypeDef) Types(io.sundr.model.utils.Types) Constants(io.sundr.builder.Constants) AptContext(io.sundr.adapter.apt.AptContext) Strings(io.sundr.utils.Strings) TypedVisitor(io.sundr.builder.TypedVisitor) BuilderContext(io.sundr.builder.internal.BuilderContext) SundrException(io.sundr.SundrException) Set(java.util.Set) Method(io.sundr.model.Method) TypeRef(io.sundr.model.TypeRef) Types.isAbstract(io.sundr.model.utils.Types.isAbstract) Setter(io.sundr.model.utils.Setter) AnnotationRef(io.sundr.model.AnnotationRef) Collectors(java.util.stream.Collectors) Property(io.sundr.model.Property) List(java.util.List) ClassRefBuilder(io.sundr.model.ClassRefBuilder) MethodBuilder(io.sundr.model.MethodBuilder) TypeArguments(io.sundr.model.utils.TypeArguments) Statement(io.sundr.model.Statement) TypeDef(io.sundr.model.TypeDef) Optional(java.util.Optional) PropertyBuilder(io.sundr.model.PropertyBuilder) BuilderContextManager(io.sundr.builder.internal.BuilderContextManager) TypeParamDef(io.sundr.model.TypeParamDef) ClassRef(io.sundr.model.ClassRef) RichTypeDef(io.sundr.model.RichTypeDef) TypeDef(io.sundr.model.TypeDef) Method(io.sundr.model.Method)

Example 14 with Method

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;
}
Also used : TypeParamRef(io.sundr.model.TypeParamRef) RichTypeDef(io.sundr.model.RichTypeDef) TypeDef(io.sundr.model.TypeDef) StringStatement(io.sundr.model.StringStatement) Statement(io.sundr.model.Statement) ArrayList(java.util.ArrayList) Method(io.sundr.model.Method) StringStatement(io.sundr.model.StringStatement) Property(io.sundr.model.Property)

Example 15 with Method

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());
    });
}
Also used : TypeParamDefBuilder(io.sundr.model.TypeParamDefBuilder) Types.modifiersToInt(io.sundr.model.utils.Types.modifiersToInt) Modifier(javax.lang.model.element.Modifier) Assert.assertNotNull(org.junit.Assert.assertNotNull) DefinitionRepository(io.sundr.model.repo.DefinitionRepository) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Method(io.sundr.model.Method) Kind(io.sundr.model.Kind) TypeDefBuilder(io.sundr.model.TypeDefBuilder) Property(io.sundr.model.Property) ClassRef(io.sundr.model.ClassRef) TypeDef(io.sundr.model.TypeDef) Optional(java.util.Optional) TypeParamDef(io.sundr.model.TypeParamDef) Assert.assertEquals(org.junit.Assert.assertEquals) Before(org.junit.Before) ClassRef(io.sundr.model.ClassRef) TypeDef(io.sundr.model.TypeDef) Method(io.sundr.model.Method) Test(org.junit.Test)

Aggregations

Method (io.sundr.model.Method)30 TypeDef (io.sundr.model.TypeDef)21 ClassRef (io.sundr.model.ClassRef)20 Property (io.sundr.model.Property)18 TypeRef (io.sundr.model.TypeRef)17 ArrayList (java.util.ArrayList)17 AnnotationRef (io.sundr.model.AnnotationRef)14 TypeDefBuilder (io.sundr.model.TypeDefBuilder)14 MethodBuilder (io.sundr.model.MethodBuilder)13 RichTypeDef (io.sundr.model.RichTypeDef)13 TypeParamDef (io.sundr.model.TypeParamDef)9 HashSet (java.util.HashSet)9 List (java.util.List)9 PropertyBuilder (io.sundr.model.PropertyBuilder)8 Set (java.util.Set)8 Collectors (java.util.stream.Collectors)8 AttributeKey (io.sundr.model.AttributeKey)7 Statement (io.sundr.model.Statement)7 StringStatement (io.sundr.model.StringStatement)7 Types (io.sundr.model.utils.Types)7