Search in sources :

Example 1 with CtReference

use of spoon.reflect.reference.CtReference in project spoon by INRIA.

the class ReferenceBuilder method getExecutableReference.

@SuppressWarnings("unchecked")
<T> CtExecutableReference<T> getExecutableReference(MethodBinding exec) {
    if (exec == null) {
        return null;
    }
    final CtExecutableReference ref = this.jdtTreeBuilder.getFactory().Core().createExecutableReference();
    if (exec.isConstructor()) {
        ref.setSimpleName(CtExecutableReference.CONSTRUCTOR_NAME);
        ref.setType(getTypeReference(exec.declaringClass));
    } else {
        ref.setSimpleName(new String(exec.selector));
        ref.setType(getTypeReference(exec.returnType));
    }
    if (exec instanceof ProblemMethodBinding) {
        if (exec.declaringClass != null && Arrays.asList(exec.declaringClass.methods()).contains(exec)) {
            ref.setDeclaringType(getTypeReference(exec.declaringClass));
        } else {
            final CtReference declaringType = getDeclaringReferenceFromImports(exec.constantPoolName());
            if (declaringType instanceof CtTypeReference) {
                ref.setDeclaringType((CtTypeReference<?>) declaringType);
            }
        }
        if (exec.isConstructor()) {
            // super() invocation have a good declaring class.
            ref.setDeclaringType(getTypeReference(exec.declaringClass));
        }
        ref.setStatic(true);
    } else {
        ref.setDeclaringType(getTypeReference(exec.declaringClass));
        ref.setStatic(exec.isStatic());
    }
    if (exec.declaringClass instanceof ParameterizedTypeBinding) {
        ref.setDeclaringType(getTypeReference(exec.declaringClass.actualType()));
    }
    // original() method returns a result not null when the current method is generic.
    if (exec.original() != null) {
        final List<CtTypeReference<?>> parameters = new ArrayList<>(exec.original().parameters.length);
        for (TypeBinding b : exec.original().parameters) {
            parameters.add(getTypeReference(b));
        }
        ref.setParameters(parameters);
    } else if (exec.parameters != null) {
        // This is a method without a generic argument.
        final List<CtTypeReference<?>> parameters = new ArrayList<>();
        for (TypeBinding b : exec.parameters) {
            parameters.add(getTypeReference(b));
        }
        ref.setParameters(parameters);
    }
    return ref;
}
Also used : ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) ProblemMethodBinding(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) CtReference(spoon.reflect.reference.CtReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) BinaryTypeBinding(org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding) ParameterizedTypeBinding(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding) TypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) MissingTypeBinding(org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding) SourceTypeBinding(org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding) JDTTreeBuilderQuery.searchTypeBinding(spoon.support.compiler.jdt.JDTTreeBuilderQuery.searchTypeBinding) PolyTypeBinding(org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding) LocalTypeBinding(org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) BaseTypeBinding(org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding) RawTypeBinding(org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding) ArrayList(java.util.ArrayList) CtExecutableReference(spoon.reflect.reference.CtExecutableReference) List(java.util.List) ArrayList(java.util.ArrayList)

Example 2 with CtReference

use of spoon.reflect.reference.CtReference in project spoon by INRIA.

the class CtTypeTest method getTypeName.

private String getTypeName(CtTypeReference<?> ref) {
    String name;
    CtReference r = ref.getParent(CtReference.class);
    if (r != null) {
        name = r.getSimpleName();
    } else {
        name = ref.getParent(CtNamedElement.class).getSimpleName();
    }
    return ref.toString() + " " + name;
}
Also used : CtReference(spoon.reflect.reference.CtReference)

Example 3 with CtReference

use of spoon.reflect.reference.CtReference 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)

Example 4 with CtReference

use of spoon.reflect.reference.CtReference in project spoon by INRIA.

the class ImportScannerImpl method addClassImport.

/**
 * Adds a type to the classImports.
 */
protected boolean addClassImport(CtTypeReference<?> ref) {
    this.exploredReferences.add(ref);
    if (ref == null) {
        return false;
    }
    if (targetType != null && targetType.getSimpleName().equals(ref.getSimpleName()) && !targetType.equals(ref)) {
        return false;
    }
    if (classImports.containsKey(ref.getSimpleName())) {
        return isImportedInClassImports(ref);
    }
    // don't import unnamed package elements
    if (ref.getPackage() == null || ref.getPackage().isUnnamedPackage()) {
        return false;
    }
    if (targetType != null && targetType.canAccess(ref) == false) {
        // ref type is not visible in targetType we must not add import for it, java compiler would fail on that.
        return false;
    }
    if (this.isThereAnotherClassWithSameNameInAnotherPackage(ref)) {
        return false;
    }
    if (targetType != null) {
        try {
            CtElement parent = ref.getParent();
            if (parent != null) {
                parent = parent.getParent();
                if (parent != null) {
                    if ((parent instanceof CtFieldAccess) || (parent instanceof CtExecutable) || (parent instanceof CtInvocation)) {
                        CtTypeReference declaringType;
                        CtReference reference;
                        CtPackageReference pack = targetType.getPackage();
                        if (parent instanceof CtFieldAccess) {
                            CtFieldAccess field = (CtFieldAccess) parent;
                            CtFieldReference localReference = field.getVariable();
                            declaringType = localReference.getDeclaringType();
                            reference = localReference;
                        } else if (parent instanceof CtExecutable) {
                            CtExecutable exec = (CtExecutable) parent;
                            CtExecutableReference localReference = exec.getReference();
                            declaringType = localReference.getDeclaringType();
                            reference = localReference;
                        } else if (parent instanceof CtInvocation) {
                            CtInvocation invo = (CtInvocation) parent;
                            CtExecutableReference localReference = invo.getExecutable();
                            declaringType = localReference.getDeclaringType();
                            reference = localReference;
                        } else {
                            declaringType = null;
                            reference = null;
                        }
                        if (reference != null && isImported(reference)) {
                            // if we are in the **same** package we do the import for test with method isImported
                            if (declaringType != null) {
                                if (declaringType.getPackage() != null && !declaringType.getPackage().isUnnamedPackage()) {
                                    // ignore java.lang package
                                    if (!declaringType.getPackage().getSimpleName().equals("java.lang")) {
                                        // ignore type in same package
                                        if (declaringType.getPackage().getSimpleName().equals(pack.getSimpleName())) {
                                            classImports.put(ref.getSimpleName(), ref);
                                            return true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (ParentNotInitializedException e) {
        }
        CtPackageReference pack = targetType.getPackage();
        if (pack != null && ref.getPackage() != null && !ref.getPackage().isUnnamedPackage()) {
            // ignore java.lang package
            if (!ref.getPackage().getSimpleName().equals("java.lang")) {
                // ignore type in same package
                if (ref.getPackage().getSimpleName().equals(pack.getSimpleName())) {
                    return false;
                }
            }
        }
    }
    classImports.put(ref.getSimpleName(), ref);
    return true;
}
Also used : CtFieldAccess(spoon.reflect.code.CtFieldAccess) CtInvocation(spoon.reflect.code.CtInvocation) ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) CtPackageReference(spoon.reflect.reference.CtPackageReference) CtReference(spoon.reflect.reference.CtReference) CtElement(spoon.reflect.declaration.CtElement) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtFieldReference(spoon.reflect.reference.CtFieldReference) CtExecutableReference(spoon.reflect.reference.CtExecutableReference) CtExecutable(spoon.reflect.declaration.CtExecutable)

Example 5 with CtReference

use of spoon.reflect.reference.CtReference in project spoon by INRIA.

the class CloneTest method testCopyType.

@Test
public void testCopyType() throws Exception {
    // contract: the copied type is well formed, it never points to the initial type
    Factory factory = ModelUtils.build(new File("./src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java"));
    CtType<?> intialElement = factory.Type().get(DefaultJavaPrettyPrinter.class);
    CtType<?> cloneTarget = intialElement.copyType();
    assertEquals("spoon.reflect.visitor.DefaultJavaPrettyPrinterCopy", cloneTarget.getQualifiedName());
    // we go over all references
    for (CtReference reference : cloneTarget.getElements(new TypeFilter<>(CtReference.class))) {
        CtElement declaration = reference.getDeclaration();
        if (declaration == null) {
            continue;
        }
        // the core assertion: not a single reference points to the initial element
        if (declaration.hasParent(intialElement)) {
            fail();
        }
    }
}
Also used : CtReference(spoon.reflect.reference.CtReference) CtElement(spoon.reflect.declaration.CtElement) Factory(spoon.reflect.factory.Factory) File(java.io.File) Test(org.junit.Test)

Aggregations

CtReference (spoon.reflect.reference.CtReference)14 CtTypeReference (spoon.reflect.reference.CtTypeReference)9 CtElement (spoon.reflect.declaration.CtElement)5 CtInvocation (spoon.reflect.code.CtInvocation)4 List (java.util.List)3 CtField (spoon.reflect.declaration.CtField)3 CtNamedElement (spoon.reflect.declaration.CtNamedElement)3 CtExecutableReference (spoon.reflect.reference.CtExecutableReference)3 CtPackageReference (spoon.reflect.reference.CtPackageReference)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 BaseTypeBinding (org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding)2 BinaryTypeBinding (org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding)2 LocalTypeBinding (org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding)2 MissingTypeBinding (org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding)2 ParameterizedTypeBinding (org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding)2 PolyTypeBinding (org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding)2 RawTypeBinding (org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding)2 ReferenceBinding (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)2 SourceTypeBinding (org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding)2