Search in sources :

Example 1 with RoleHandler

use of spoon.reflect.meta.RoleHandler in project spoon by INRIA.

the class RoleHandlerHelper method getRoleHandlers.

/**
 * @param targetClass a Class whose handlers we are looking for
 * @return all {@link RoleHandler}s available for the `targetClass`
 */
public static List<RoleHandler> getRoleHandlers(Class<? extends CtElement> targetClass) {
    List<RoleHandler> handlers = roleHandlersByClass.get(targetClass);
    if (handlers == null) {
        List<RoleHandler> modifiableHandlers = new ArrayList<>();
        for (CtRole role : CtRole.values()) {
            RoleHandler roleHandler = getOptionalRoleHandler(targetClass, role);
            if (roleHandler != null) {
                modifiableHandlers.add(roleHandler);
            }
        }
        handlers = Collections.unmodifiableList(modifiableHandlers);
        roleHandlersByClass.put(targetClass, handlers);
    }
    return handlers;
}
Also used : RoleHandler(spoon.reflect.meta.RoleHandler) ArrayList(java.util.ArrayList) CtRole(spoon.reflect.path.CtRole)

Example 2 with RoleHandler

use of spoon.reflect.meta.RoleHandler in project spoon by INRIA.

the class MetaModelTest method checkRoleHandlersOfType.

private void checkRoleHandlersOfType(CtType iface) {
    Class ifaceClass = iface.getActualClass();
    // contract: check that for each Spoon model interface we have correct list of Role handlers
    List<RoleHandler> roleHandlersOfIFace = new ArrayList<>(RoleHandlerHelper.getRoleHandlers(ifaceClass));
    Set<RoleHandler> allRoleHandlers = new HashSet<>();
    RoleHandlerHelper.forEachRoleHandler(rh -> allRoleHandlers.add(rh));
    for (CtRole role : CtRole.values()) {
        RoleHandler rh = RoleHandlerHelper.getOptionalRoleHandler(ifaceClass, role);
        if (rh != null) {
            assertTrue("RoleHandler for role " + role + " is missing for " + ifaceClass, roleHandlersOfIFace.remove(rh));
            assertTrue("RoleHandler " + rh + " is not accessible by RoleHandlerHelper#forEachRoleHandler()", allRoleHandlers.contains(rh));
        }
    }
    assertTrue("There are unexpected RoleHandlers " + roleHandlersOfIFace + " for " + ifaceClass, roleHandlersOfIFace.isEmpty());
}
Also used : RoleHandler(spoon.reflect.meta.RoleHandler) ArrayList(java.util.ArrayList) CtRole(spoon.reflect.path.CtRole) CtClass(spoon.reflect.declaration.CtClass) HashSet(java.util.HashSet)

Example 3 with RoleHandler

use of spoon.reflect.meta.RoleHandler in project spoon by INRIA.

the class MetaModelTest method elementAnnotationRoleHandlerTest.

@Test
public void elementAnnotationRoleHandlerTest() {
    Launcher launcher = new Launcher();
    Factory factory = launcher.getFactory();
    CtClass<?> type = (CtClass) factory.Core().create(CtClass.class);
    CtAnnotation<?> annotation = factory.Annotation().annotate(type, Parameter.class, "value", "abc");
    // check contract of low level RoleHandler
    RoleHandler roleHandler = RoleHandlerHelper.getRoleHandler(type.getClass(), CtRole.ANNOTATION);
    assertNotNull(roleHandler);
    assertEquals(CtElement.class, roleHandler.getTargetType());
    assertSame(CtRole.ANNOTATION, roleHandler.getRole());
    assertSame(ContainerKind.LIST, roleHandler.getContainerKind());
    assertEquals(CtAnnotation.class, roleHandler.getValueClass());
    // check getting value using role handler
    List<CtAnnotation<?>> value = roleHandler.getValue(type);
    assertEquals(1, value.size());
    assertSame(annotation, value.get(0));
    // check we have got direct readonly List
    try {
        value.remove(annotation);
        fail();
    } catch (Exception e) {
        this.getClass();
    }
    // check setValueByRole
    roleHandler.setValue(type, Collections.emptyList());
    value = roleHandler.getValue(type);
    assertEquals(0, value.size());
    roleHandler.setValue(type, Collections.singletonList(annotation));
    value = roleHandler.getValue(type);
    assertEquals(1, value.size());
    assertSame(annotation, value.get(0));
    try {
        // contract value must be a list of annotation. One annotation is not actually OK. This contract might be changed in future
        roleHandler.setValue(type, annotation);
        fail();
    } catch (ClassCastException e) {
    // OK
    }
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtAnnotation(spoon.reflect.declaration.CtAnnotation) RoleHandler(spoon.reflect.meta.RoleHandler) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) SpoonException(spoon.SpoonException) Test(org.junit.Test)

Example 4 with RoleHandler

use of spoon.reflect.meta.RoleHandler in project spoon by INRIA.

the class CtRolePathElement method getElements.

@Override
public Collection<CtElement> getElements(Collection<CtElement> roots) {
    Collection<CtElement> matchs = new LinkedList<>();
    for (CtElement root : roots) {
        RoleHandler roleHandler = RoleHandlerHelper.getOptionalRoleHandler(root.getClass(), getRole());
        if (roleHandler != null) {
            switch(roleHandler.getContainerKind()) {
                case SINGLE:
                    if (roleHandler.getValue(root) != null) {
                        matchs.add(roleHandler.getValue(root));
                    }
                    break;
                case LIST:
                    if (getArguments().containsKey("index")) {
                        int index = Integer.parseInt(getArguments().get("index"));
                        if (index < roleHandler.asList(root).size()) {
                            matchs.add((CtElement) roleHandler.asList(root).get(index));
                        }
                    } else {
                        matchs.addAll(roleHandler.asList(root));
                    }
                    break;
                case SET:
                    if (getArguments().containsKey("name")) {
                        String name = getArguments().get("name");
                        try {
                            CtElement match = getFromSet(roleHandler.asSet(root), name);
                            if (match != null) {
                                matchs.add(match);
                            }
                        } catch (CtPathException e) {
                        // System.err.println("[ERROR] Element not found for name: " + name);
                        // No element found for name.
                        }
                    } else {
                        matchs.addAll(roleHandler.asSet(root));
                    }
                    break;
                case MAP:
                    if (getArguments().containsKey("key")) {
                        String name = getArguments().get("key");
                        if (roleHandler.asMap(root).containsKey(name)) {
                            matchs.add((CtElement) roleHandler.asMap(root).get(name));
                        }
                    } else {
                        Map<String, CtElement> map = roleHandler.asMap(root);
                        matchs.addAll(map.values());
                    }
                    break;
            }
        }
    }
    return matchs;
}
Also used : CtElement(spoon.reflect.declaration.CtElement) RoleHandler(spoon.reflect.meta.RoleHandler) LinkedList(java.util.LinkedList) CtPathException(spoon.reflect.path.CtPathException)

Example 5 with RoleHandler

use of spoon.reflect.meta.RoleHandler in project spoon by INRIA.

the class CtElementPathBuilder method fromElement.

/**
 * Build path to a CtElement el, from one of its parent.
 *
 * @throws CtPathException is thrown when root is not a parent of el.
 *
 * @param el : the element to which the CtPath leads to
 * @param root : Starting point of the CtPath
 * @return CtPath from root to el
 */
public CtPath fromElement(CtElement el, CtElement root) throws CtPathException {
    CtPathImpl path = new CtPathImpl();
    CtElement cur = el;
    while (cur != root) {
        CtElement parent = cur.getParent();
        CtRole role = cur.getRoleInParent();
        if (role == null) {
            throw new CtPathException();
        }
        RoleHandler roleHandler = RoleHandlerHelper.getOptionalRoleHandler(parent.getClass(), role);
        if (roleHandler == null) {
            throw new CtPathException();
        }
        CtPathElement pathElement = new CtRolePathElement(role);
        switch(roleHandler.getContainerKind()) {
            case SINGLE:
                break;
            case LIST:
                // Element needs to be differentiated from its brothers
                List list = roleHandler.asList(parent);
                // Assumes that List's order is deterministic.
                // Can't be replaced by list.indexOf(cur)
                // Because objects must be the same (and not just equals)
                int index = 0;
                for (Object o : list) {
                    if (o == cur) {
                        break;
                    }
                    index++;
                }
                pathElement.addArgument("index", index + "");
                break;
            case SET:
                String name;
                if (cur instanceof CtNamedElement) {
                    name = ((CtNamedElement) cur).getSimpleName();
                } else if (cur instanceof CtReference) {
                    name = ((CtReference) cur).getSimpleName();
                } else {
                    throw new CtPathException();
                }
                pathElement.addArgument("name", name);
                break;
            case MAP:
                Map map = roleHandler.asMap(parent);
                String key = null;
                for (Object o : map.keySet()) {
                    if (map.get(o) == cur) {
                        key = (String) o;
                        break;
                    }
                }
                if (key == null) {
                    throw new CtPathException();
                } else {
                    pathElement.addArgument("key", key);
                }
                break;
        }
        cur = parent;
        path.addFirst(pathElement);
    }
    return path;
}
Also used : CtElement(spoon.reflect.declaration.CtElement) RoleHandler(spoon.reflect.meta.RoleHandler) CtPathElement(spoon.reflect.path.impl.CtPathElement) CtRolePathElement(spoon.reflect.path.impl.CtRolePathElement) CtPathImpl(spoon.reflect.path.impl.CtPathImpl) CtReference(spoon.reflect.reference.CtReference) List(java.util.List) CtNamedElement(spoon.reflect.declaration.CtNamedElement) Map(java.util.Map)

Aggregations

RoleHandler (spoon.reflect.meta.RoleHandler)10 Test (org.junit.Test)5 Launcher (spoon.Launcher)4 CtElement (spoon.reflect.declaration.CtElement)4 CtRole (spoon.reflect.path.CtRole)4 ArrayList (java.util.ArrayList)3 SpoonException (spoon.SpoonException)3 Factory (spoon.reflect.factory.Factory)3 CtClass (spoon.reflect.declaration.CtClass)2 ArrayDeque (java.util.ArrayDeque)1 Deque (java.util.Deque)1 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 CtBlock (spoon.reflect.code.CtBlock)1 CtStatement (spoon.reflect.code.CtStatement)1 CtAnnotation (spoon.reflect.declaration.CtAnnotation)1 CtField (spoon.reflect.declaration.CtField)1 CtNamedElement (spoon.reflect.declaration.CtNamedElement)1