Search in sources :

Example 1 with CtField

use of spoon.reflect.declaration.CtField 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 2 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class FilterTest method testFieldAccessFilter.

@Test
public void testFieldAccessFilter() throws Exception {
    // also specifies VariableAccessFilter since FieldAccessFilter is only a VariableAccessFilter with additional static typing
    CtClass<?> foo = factory.Package().get("spoon.test.filters").getType("Foo");
    assertEquals("Foo", foo.getSimpleName());
    List<CtNamedElement> elements = foo.getElements(new NamedElementFilter<>(CtNamedElement.class, "i"));
    assertEquals(1, elements.size());
    CtFieldReference<?> ref = (CtFieldReference<?>) (elements.get(0)).getReference();
    List<CtFieldAccess<?>> expressions = foo.getElements(new FieldAccessFilter(ref));
    assertEquals(2, expressions.size());
    final Factory build = build(FieldAccessFilterTacos.class);
    final CtType<FieldAccessFilterTacos> fieldAccessFilterTacos = build.Type().get(FieldAccessFilterTacos.class);
    try {
        List<CtField> fields = fieldAccessFilterTacos.getElements(new TypeFilter<CtField>(CtField.class));
        for (CtField ctField : fields) {
            fieldAccessFilterTacos.getElements(new FieldAccessFilter(ctField.getReference()));
        }
    } catch (NullPointerException e) {
        fail("FieldAccessFilter must not throw a NPE.");
    }
}
Also used : CtFieldAccess(spoon.reflect.code.CtFieldAccess) CtFieldReference(spoon.reflect.reference.CtFieldReference) Factory(spoon.reflect.factory.Factory) FieldAccessFilterTacos(spoon.test.filters.testclasses.FieldAccessFilterTacos) CtField(spoon.reflect.declaration.CtField) CtNamedElement(spoon.reflect.declaration.CtNamedElement) FieldAccessFilter(spoon.reflect.visitor.filter.FieldAccessFilter) Test(org.junit.Test)

Example 3 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class FilterTest method testNameFilterWithGenericType.

@Test
public void testNameFilterWithGenericType() {
    // contract: NamedElementFilter of T should only return T elements
    Launcher spoon = new Launcher();
    spoon.addInputResource("./src/test/java/spoon/test/imports/testclasses/internal4/Constants.java");
    spoon.buildModel();
    CtType type = spoon.getFactory().Type().get(Constants.class);
    List<CtMethod> ctMethods = type.getElements(new NamedElementFilter<>(CtMethod.class, "CONSTANT"));
    assertTrue(ctMethods.isEmpty());
    List<CtField> ctFields = type.getElements(new NamedElementFilter<>(CtField.class, "CONSTANT"));
    assertEquals(1, ctFields.size());
    assertTrue(ctFields.get(0) instanceof CtField);
}
Also used : CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 4 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class ImportTest method testGetImportKindReturnRightValue.

@Test
public void testGetImportKindReturnRightValue() {
    // contract: the importKind is computed based on the reference class type and the boolean isImportAllStaticTypeMembers
    final Launcher spoon = new Launcher();
    CtType aType = spoon.getFactory().Type().get(Reflection.class);
    CtImport ctImport = spoon.getFactory().createImport(aType.getReference());
    assertEquals(CtImportKind.TYPE, ctImport.getImportKind());
    ctImport = spoon.getFactory().createImport(spoon.getFactory().Type().createWildcardStaticTypeMemberReference(aType.getReference()));
    assertEquals(CtImportKind.ALL_STATIC_MEMBERS, ctImport.getImportKind());
    ctImport = spoon.getFactory().createImport(((CtMethod) aType.getAllMethods().iterator().next()).getReference());
    assertEquals(CtImportKind.METHOD, ctImport.getImportKind());
    ctImport = spoon.getFactory().createImport(((CtField) aType.getFields().get(0)).getReference());
    assertEquals(CtImportKind.FIELD, ctImport.getImportKind());
    ctImport = spoon.getFactory().createImport(aType.getPackage().getReference());
    assertEquals(CtImportKind.ALL_TYPES, ctImport.getImportKind());
}
Also used : CtImport(spoon.reflect.declaration.CtImport) CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 5 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class ImportScannerImpl method isTypeInCollision.

/**
 * Test if the reference can be imported, i.e. test if the importation could lead to a collision.
 * @param ref
 * @return true if the ref should be imported.
 */
protected boolean isTypeInCollision(CtReference ref, boolean fqnMode) {
    if (targetType != null && targetType.getSimpleName().equals(ref.getSimpleName()) && !targetType.equals(ref)) {
        return true;
    }
    try {
        CtElement parent;
        if (ref instanceof CtTypeReference) {
            parent = ref.getParent();
        } else {
            parent = ref;
        }
        // i.e. a string, an int, etc.
        if (parent instanceof CtLiteral) {
            return false;
        }
        Set<String> localVariablesOfBlock = new HashSet<>();
        if (parent instanceof CtField) {
            this.fieldAndMethodsNames.add(((CtField) parent).getSimpleName());
        } else if (parent instanceof CtMethod) {
            this.fieldAndMethodsNames.add(((CtMethod) parent).getSimpleName());
        } else {
            localVariablesOfBlock = this.lookForLocalVariables(parent);
        }
        while (!(parent instanceof CtPackage)) {
            if ((parent instanceof CtFieldReference) || (parent instanceof CtExecutableReference) || (parent instanceof CtInvocation)) {
                CtReference parentType;
                if (parent instanceof CtInvocation) {
                    parentType = ((CtInvocation) parent).getExecutable();
                } else {
                    parentType = (CtReference) parent;
                }
                LinkedList<String> qualifiedNameTokens = new LinkedList<>();
                // we don't want to test the current ref name, as we risk to create field import and make autoreference
                if (parentType != parent) {
                    qualifiedNameTokens.add(parentType.getSimpleName());
                }
                CtTypeReference typeReference;
                if (parent instanceof CtFieldReference) {
                    typeReference = ((CtFieldReference) parent).getDeclaringType();
                } else if (parent instanceof CtExecutableReference) {
                    typeReference = ((CtExecutableReference) parent).getDeclaringType();
                } else {
                    typeReference = ((CtInvocation) parent).getExecutable().getDeclaringType();
                }
                if (typeReference != null) {
                    qualifiedNameTokens.addFirst(typeReference.getSimpleName());
                    if (typeReference.getPackage() != null) {
                        StringTokenizer token = new StringTokenizer(typeReference.getPackage().getSimpleName(), CtPackage.PACKAGE_SEPARATOR);
                        int index = 0;
                        while (token.hasMoreElements()) {
                            qualifiedNameTokens.add(index, token.nextToken());
                            index++;
                        }
                    }
                }
                if (!qualifiedNameTokens.isEmpty()) {
                    // if the first package name is a variable name somewhere, it could lead to a collision
                    if (fieldAndMethodsNames.contains(qualifiedNameTokens.getFirst()) || localVariablesOfBlock.contains(qualifiedNameTokens.getFirst())) {
                        qualifiedNameTokens.removeFirst();
                        if (fqnMode) {
                            // for example: spoon.Launcher if a field spoon and another one Launcher exists
                            if (ref instanceof CtTypeReference) {
                                if (qualifiedNameTokens.isEmpty()) {
                                    return true;
                                }
                                // but if the other package names are not a variable name, it's ok to import
                                for (int i = 0; i < qualifiedNameTokens.size(); i++) {
                                    String testedToken = qualifiedNameTokens.get(i);
                                    if (!fieldAndMethodsNames.contains(testedToken) && !localVariablesOfBlock.contains(testedToken)) {
                                        return true;
                                    }
                                }
                                return false;
                            // However if it is a static method/field, we always accept to import them in this case
                            // It is the last possibility for managing import for us
                            } else {
                                return true;
                            }
                        } else {
                            // but if the other package names are not a variable name, it's ok to import
                            for (int i = 0; i < qualifiedNameTokens.size(); i++) {
                                String testedToken = qualifiedNameTokens.get(i);
                                if (!fieldAndMethodsNames.contains(testedToken) && !localVariablesOfBlock.contains(testedToken)) {
                                    return false;
                                }
                            }
                            return true;
                        }
                    }
                }
            }
            parent = parent.getParent();
        }
    } catch (ParentNotInitializedException e) {
        return false;
    }
    return false;
}
Also used : ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) CtElement(spoon.reflect.declaration.CtElement) CtFieldReference(spoon.reflect.reference.CtFieldReference) LinkedList(java.util.LinkedList) CtInvocation(spoon.reflect.code.CtInvocation) StringTokenizer(java.util.StringTokenizer) CtLiteral(spoon.reflect.code.CtLiteral) CtReference(spoon.reflect.reference.CtReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) CtExecutableReference(spoon.reflect.reference.CtExecutableReference) CtPackage(spoon.reflect.declaration.CtPackage) CtMethod(spoon.reflect.declaration.CtMethod) HashSet(java.util.HashSet)

Aggregations

CtField (spoon.reflect.declaration.CtField)39 Test (org.junit.Test)20 Launcher (spoon.Launcher)16 CtType (spoon.reflect.declaration.CtType)16 CtMethod (spoon.reflect.declaration.CtMethod)13 CtTypeReference (spoon.reflect.reference.CtTypeReference)12 ArrayList (java.util.ArrayList)8 CtElement (spoon.reflect.declaration.CtElement)8 CtClass (spoon.reflect.declaration.CtClass)6 CtTypeMember (spoon.reflect.declaration.CtTypeMember)6 Factory (spoon.reflect.factory.Factory)6 List (java.util.List)5 SpoonException (spoon.SpoonException)5 CtExecutable (spoon.reflect.declaration.CtExecutable)5 CtPackage (spoon.reflect.declaration.CtPackage)5 CtParameter (spoon.reflect.declaration.CtParameter)5 CtLocalVariable (spoon.reflect.code.CtLocalVariable)4 CtFieldReference (spoon.reflect.reference.CtFieldReference)4 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)4 Set (java.util.Set)3