Search in sources :

Example 1 with CtScanner

use of spoon.reflect.visitor.CtScanner in project spoon by INRIA.

the class TypeFactory method get.

/**
 * Gets a type from its runtime Java class. If the class isn't in the spoon path,
 * the class will be build from the Java reflection and will be marked as
 * shadow (see {@link spoon.reflect.declaration.CtShadowable}).
 *
 * @param <T>
 * 		actual type of the class
 * @param cl
 * 		the java class: note that this class should be Class&lt;T&gt; but it
 * 		then poses problem when T is a generic type itself
 */
@SuppressWarnings("unchecked")
public <T> CtType<T> get(Class<?> cl) {
    final CtType<T> aType = get(cl.getName());
    if (aType == null) {
        final CtType<T> shadowClass = (CtType<T>) this.shadowCache.get(cl);
        if (shadowClass == null) {
            CtType<T> newShadowClass;
            try {
                newShadowClass = new JavaReflectionTreeBuilder(createFactory()).scan((Class<T>) cl);
            } catch (Throwable e) {
                throw new SpoonClassNotFoundException("cannot create shadow class: " + cl.getName(), e);
            }
            newShadowClass.setFactory(factory);
            newShadowClass.accept(new CtScanner() {

                @Override
                public void scan(CtElement element) {
                    if (element != null) {
                        element.setFactory(factory);
                    }
                }
            });
            this.shadowCache.put(cl, newShadowClass);
            return newShadowClass;
        } else {
            return shadowClass;
        }
    }
    return aType;
}
Also used : CtType(spoon.reflect.declaration.CtType) JavaReflectionTreeBuilder(spoon.support.visitor.java.JavaReflectionTreeBuilder) CtElement(spoon.reflect.declaration.CtElement) SpoonClassNotFoundException(spoon.support.SpoonClassNotFoundException) CtNewClass(spoon.reflect.code.CtNewClass) CtClass(spoon.reflect.declaration.CtClass) CtScanner(spoon.reflect.visitor.CtScanner)

Example 2 with CtScanner

use of spoon.reflect.visitor.CtScanner in project spoon by INRIA.

the class Refactoring method copyType.

/**
 * See doc in {@link CtType#copyType()}
 */
public static CtType<?> copyType(final CtType<?> type) {
    CtType<?> clone = type.clone();
    String tentativeTypeName = type.getSimpleName() + "Copy";
    while (type.getFactory().Type().get(type.getPackage().getQualifiedName() + "." + tentativeTypeName) != null) {
        tentativeTypeName += "X";
    }
    final String cloneTypeName = tentativeTypeName;
    clone.setSimpleName(cloneTypeName);
    type.getPackage().addType(clone);
    new CtScanner() {

        @Override
        public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
            if (reference.getDeclaration() == null) {
                return;
            }
            if (reference.getDeclaration() == type) {
                reference.setSimpleName(cloneTypeName);
            }
            if (reference.getDeclaration() != clone) {
                throw new SpoonException("post condition broken " + reference);
            }
            super.visitCtTypeReference(reference);
        }

        @Override
        public <T> void visitCtExecutableReference(CtExecutableReference<T> reference) {
            CtExecutable<T> declaration = reference.getDeclaration();
            if (declaration == null) {
                return;
            }
            if (declaration.hasParent(type)) {
                reference.getDeclaringType().setSimpleName(cloneTypeName);
            }
            if (!reference.getDeclaration().hasParent(clone)) {
                throw new SpoonException("post condition broken " + reference);
            }
            super.visitCtExecutableReference(reference);
        }

        @Override
        public <T> void visitCtFieldReference(CtFieldReference<T> reference) {
            CtField<T> declaration = reference.getDeclaration();
            if (declaration == null) {
                return;
            }
            if (declaration.hasParent(type)) {
                reference.getDeclaringType().setSimpleName(cloneTypeName);
            }
            if (reference.getDeclaration() == null || !reference.getDeclaration().hasParent(clone)) {
                throw new SpoonException("post condition broken " + reference);
            }
            super.visitCtFieldReference(reference);
        }
    }.scan(clone);
    return clone;
}
Also used : SpoonException(spoon.SpoonException) CtField(spoon.reflect.declaration.CtField) CtScanner(spoon.reflect.visitor.CtScanner) CtExecutable(spoon.reflect.declaration.CtExecutable)

Example 3 with CtScanner

use of spoon.reflect.visitor.CtScanner in project spoon by INRIA.

the class SiblingsFunction method apply.

@Override
public void apply(final CtElement input, final CtConsumer<Object> outputConsumer) {
    final CtElement parent = input.getParent();
    parent.accept(new CtScanner() {

        boolean hasVisitedInput = false;

        boolean visitPrev = mode == Mode.ALL || mode == Mode.PREVIOUS;

        boolean visitNext = mode == Mode.ALL || mode == Mode.NEXT;

        @Override
        public void scan(CtElement element) {
            if (element != null && element.isParentInitialized() && element.getParent() == parent) {
                // visit only elements whose parent is same
                boolean canVisit = hasVisitedInput ? visitNext : visitPrev;
                if (input == element) {
                    hasVisitedInput = true;
                    canVisit = includingSelf;
                }
                if (canVisit) {
                    outputConsumer.accept(element);
                }
            }
        }
    });
}
Also used : CtElement(spoon.reflect.declaration.CtElement) CtScanner(spoon.reflect.visitor.CtScanner)

Example 4 with CtScanner

use of spoon.reflect.visitor.CtScanner in project spoon by INRIA.

the class SubstitutionVisitor method substitute.

/**
 * Substitutes all template parameters of element and returns substituted element.
 *
 * @param element to be substituted model
 * @return substituted model
 */
public <E extends CtElement> List<E> substitute(E element) {
    final Map<CtElement, String> elementToGeneratedByComment = addGeneratedBy ? new IdentityHashMap<CtElement, String>() : null;
    if (addGeneratedBy) {
        /*
			 * collect 'generated by' comments for each type member of the substituted element, before the substitution is done,
			 * so we know the origin names of the members.
			 */
        final CtInheritanceScanner internalScanner = new CtInheritanceScanner() {

            public void scanCtTypeMember(CtTypeMember typeMeber) {
                elementToGeneratedByComment.put(typeMeber, getGeneratedByComment(typeMeber));
            }
        };
        new CtScanner() {

            @Override
            public void scan(CtElement p_element) {
                internalScanner.scan(p_element);
                super.scan(p_element);
            }
        }.scan(element);
    }
    List<E> result = createContext().substitute(element);
    if (addGeneratedBy) {
        // add generated by comments after substitution, otherwise they would be substituted in comments too.
        applyGeneratedByComments(elementToGeneratedByComment);
    }
    return result;
}
Also used : CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtElement(spoon.reflect.declaration.CtElement) CtInheritanceScanner(spoon.reflect.visitor.CtInheritanceScanner) CtScanner(spoon.reflect.visitor.CtScanner)

Example 5 with CtScanner

use of spoon.reflect.visitor.CtScanner in project spoon by INRIA.

the class MainTest method checkParentConsistency.

public static void checkParentConsistency(CtElement ele) {
    final Set<CtElement> inconsistentParents = new HashSet<>();
    new CtScanner() {

        private Deque<CtElement> previous = new ArrayDeque();

        @Override
        protected void enter(CtElement e) {
            if (e != null) {
                if (!previous.isEmpty()) {
                    try {
                        if (e.getParent() != previous.getLast()) {
                            inconsistentParents.add(e);
                        }
                    } catch (ParentNotInitializedException ignore) {
                        inconsistentParents.add(e);
                    }
                }
                previous.add(e);
            }
            super.enter(e);
        }

        @Override
        protected void exit(CtElement e) {
            if (e == null) {
                return;
            }
            if (e.equals(previous.getLast())) {
                previous.removeLast();
            } else {
                throw new RuntimeException("Inconsistent stack");
            }
            super.exit(e);
        }
    }.scan(ele);
    assertEquals("All parents have to be consistent", 0, inconsistentParents.size());
}
Also used : ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) CtElement(spoon.reflect.declaration.CtElement) CtScanner(spoon.reflect.visitor.CtScanner) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet)

Aggregations

CtScanner (spoon.reflect.visitor.CtScanner)18 CtElement (spoon.reflect.declaration.CtElement)9 Test (org.junit.Test)7 Launcher (spoon.Launcher)6 ArrayList (java.util.ArrayList)4 SpoonException (spoon.SpoonException)4 CtType (spoon.reflect.declaration.CtType)3 CtBlock (spoon.reflect.code.CtBlock)2 CtComment (spoon.reflect.code.CtComment)2 CtLocalVariable (spoon.reflect.code.CtLocalVariable)2 CtClass (spoon.reflect.declaration.CtClass)2 CtExecutable (spoon.reflect.declaration.CtExecutable)2 CtField (spoon.reflect.declaration.CtField)2 CtMethod (spoon.reflect.declaration.CtMethod)2 CtParameter (spoon.reflect.declaration.CtParameter)2 CtLocalVariableReference (spoon.reflect.reference.CtLocalVariableReference)2 CtTypeReference (spoon.reflect.reference.CtTypeReference)2 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)2 URLClassLoader (java.net.URLClassLoader)1 ArrayDeque (java.util.ArrayDeque)1