Search in sources :

Example 1 with InterfaceName

use of io.sundr.dsl.annotations.InterfaceName in project sundrio by sundrio.

the class TypeDefUtils method executablesToInterfaces.

/**
 * Convert a {@link Collection} of {@link javax.lang.model.element.ExecutableElement}s to a {@link java.util.Set} of
 * {@link io.sundr.model.TypeDef}es.
 *
 * @param context The context of the operation.
 * @param elements The target elements.
 * @return A set of {@link io.sundr.model.TypeDef} that describes the interfaces.
 */
public static Set<TypeDef> executablesToInterfaces(DslContext context, Collection<ExecutableElement> elements) {
    Map<String, TypeDef> byName = new LinkedHashMap<String, TypeDef>();
    for (ExecutableElement current : elements) {
        TypeDef clazz = executableToInterface(context, current);
        InterfaceName interfaceName = current.getAnnotation(InterfaceName.class);
        String name = interfaceName != null ? clazz.getPackageName() + "." + interfaceName.value() : clazz.getFullyQualifiedName();
        if (byName.containsKey(name)) {
            TypeDef other = byName.remove(name);
            byName.put(name, Merge.CLASSES.apply(new TypeDef[] { other, clazz }));
        } else {
            byName.put(name, clazz);
        }
    }
    return new LinkedHashSet<TypeDef>(byName.values());
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TypeDef(io.sundr.model.TypeDef) ExecutableElement(javax.lang.model.element.ExecutableElement) InterfaceName(io.sundr.dsl.annotations.InterfaceName) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with InterfaceName

use of io.sundr.dsl.annotations.InterfaceName 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 3 with InterfaceName

use of io.sundr.dsl.annotations.InterfaceName in project sundrio by sundrio.

the class DslProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
    Elements elements = processingEnv.getElementUtils();
    Types types = processingEnv.getTypeUtils();
    DslContext context = DslContextManager.create(elements, types);
    for (TypeElement annotation : annotations) {
        for (Element element : env.getElementsAnnotatedWith(annotation)) {
            if (element instanceof TypeElement) {
                Generics.clear();
                TypeElement typeElement = (TypeElement) element;
                InterfaceName interfaceName = element.getAnnotation(InterfaceName.class);
                String targetInterface = interfaceName.value();
                Set<TypeDef> interfacesToGenerate = new LinkedHashSet<TypeDef>();
                Collection<ExecutableElement> sorted = ElementFilter.methodsIn(typeElement.getEnclosedElements());
                // 1st step generate generic interface for all types.
                Set<TypeDef> genericInterfaces = executablesToInterfaces(context, sorted);
                Set<TypeDef> genericAndScopeInterfaces = Nodes.TO_SCOPE.apply(genericInterfaces);
                for (TypeDef clazz : genericAndScopeInterfaces) {
                    if (!TypeDefUtils.isEntryPoint(clazz)) {
                        interfacesToGenerate.add(clazz);
                    }
                }
                // 2nd step create dependency graph.
                List<Method> methods = new ArrayList<Method>();
                Set<Node<TypeDef>> graph = Nodes.TO_GRAPH.apply(genericAndScopeInterfaces);
                for (Node<TypeDef> root : graph) {
                    Node<TypeDef> uncyclic = Nodes.TO_UNCYCLIC.apply(root);
                    Node<TypeDef> unwrapped = Nodes.TO_UNWRAPPED.apply(NodeContext.builder().withItem(uncyclic.getItem()).build());
                    TypeDef current = unwrapped.getItem();
                    // Just add the method with the direct return type.
                    if (unwrapped.getTransitions().isEmpty()) {
                        for (Method m : current.getMethods()) {
                            TypeRef returnType = m.getReturnType();
                            if (returnType instanceof ClassRef) {
                                TypeDef toUnwrap = GetDefinition.of((ClassRef) returnType);
                                methods.add(new MethodBuilder(m).withReturnType(Generics.UNWRAP.apply(toUnwrap).toInternalReference()).build());
                            } else if (returnType.getAttributes().containsKey(ORIGINAL_REF)) {
                                methods.add(new MethodBuilder(m).withReturnType((TypeRef) returnType.getAttributes().get(ORIGINAL_REF)).build());
                            } else {
                                methods.add(new MethodBuilder(m).withReturnType(returnType).build());
                            }
                        }
                    } else {
                        for (Method m : current.getMethods()) {
                            methods.add(new MethodBuilder(m).withReturnType(current.toUnboundedReference()).build());
                        }
                        interfacesToGenerate.add(Nodes.TO_ROOT.apply(unwrapped));
                    }
                }
                // Do generate the DSL interface
                interfacesToGenerate.add(new TypeDefBuilder().withComments("Generated").withPackageName(Apt.getPackageElement(element).toString()).withName(targetInterface).withKind(Kind.INTERFACE).withModifiers(modifiersToInt(Modifier.PUBLIC)).withMethods(methods).build());
                interfacesToGenerate.addAll(context.getDefinitionRepository().getDefinitions(IS_GENERATED));
                for (TypeDef clazz : interfacesToGenerate) {
                    generate(clazz);
                }
            }
        }
    }
    return true;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) ClassRef(io.sundr.model.ClassRef) TypeElement(javax.lang.model.element.TypeElement) TypeRef(io.sundr.model.TypeRef) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) Node(io.sundr.dsl.internal.graph.Node) ArrayList(java.util.ArrayList) Method(io.sundr.model.Method) Elements(javax.lang.model.util.Elements) TypeDefBuilder(io.sundr.model.TypeDefBuilder) MethodBuilder(io.sundr.model.MethodBuilder) TypeDef(io.sundr.model.TypeDef) InterfaceName(io.sundr.dsl.annotations.InterfaceName)

Aggregations

InterfaceName (io.sundr.dsl.annotations.InterfaceName)3 LinkedHashSet (java.util.LinkedHashSet)3 Method (io.sundr.model.Method)2 MethodBuilder (io.sundr.model.MethodBuilder)2 TypeDef (io.sundr.model.TypeDef)2 TypeDefBuilder (io.sundr.model.TypeDefBuilder)2 TypeRef (io.sundr.model.TypeRef)2 ArrayList (java.util.ArrayList)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 Begin (io.sundr.dsl.annotations.Begin)1 End (io.sundr.dsl.annotations.End)1 EntryPoint (io.sundr.dsl.annotations.EntryPoint)1 MethodName (io.sundr.dsl.annotations.MethodName)1 Multiple (io.sundr.dsl.annotations.Multiple)1 AndTransitionFilter (io.sundr.dsl.internal.element.functions.filter.AndTransitionFilter)1 OrTransitionFilter (io.sundr.dsl.internal.element.functions.filter.OrTransitionFilter)1 TransitionFilter (io.sundr.dsl.internal.element.functions.filter.TransitionFilter)1 Node (io.sundr.dsl.internal.graph.Node)1 AnnotationRef (io.sundr.model.AnnotationRef)1 ClassRef (io.sundr.model.ClassRef)1