Search in sources :

Example 1 with CtFormalTypeDeclarer

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

the class CtTypeParameterTest method checkType.

private void checkType(CtType<?> type) throws NoSuchFieldException, SecurityException {
    List<CtTypeParameter> formalTypeParameters = type.getFormalCtTypeParameters();
    for (CtTypeParameter ctTypeParameter : formalTypeParameters) {
        checkTypeParamErasureOfType(ctTypeParameter, type.getActualClass());
    }
    for (CtTypeMember member : type.getTypeMembers()) {
        if (member instanceof CtFormalTypeDeclarer) {
            CtFormalTypeDeclarer ftDecl = (CtFormalTypeDeclarer) member;
            formalTypeParameters = ftDecl.getFormalCtTypeParameters();
            if (member instanceof CtExecutable<?>) {
                CtExecutable<?> exec = (CtExecutable<?>) member;
                for (CtTypeParameter ctTypeParameter : formalTypeParameters) {
                    checkTypeParamErasureOfExecutable(ctTypeParameter);
                }
                for (CtParameter<?> param : exec.getParameters()) {
                    checkParameterErasureOfExecutable(param);
                }
            } else if (member instanceof CtType<?>) {
                CtType<?> nestedType = (CtType<?>) member;
                // recursive call for nested type
                checkType(nestedType);
            }
        }
    }
}
Also used : CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtType(spoon.reflect.declaration.CtType) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) CtExecutable(spoon.reflect.declaration.CtExecutable)

Example 2 with CtFormalTypeDeclarer

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

the class ClassTypingContext method resolveTypeParameters.

/**
 * resolve typeRefs declared in scope of declarer using actual type arguments registered in typeScopeToActualTypeArguments
 * @param typeRefs to be resolved type references
 * @return resolved type references - one for each `typeRefs`
 * @throws SpoonException if they cannot be resolved. It should not normally happen. If it happens then spoon AST model is probably not consistent.
 */
private List<CtTypeReference<?>> resolveTypeParameters(List<CtTypeReference<?>> typeRefs) {
    List<CtTypeReference<?>> result = new ArrayList<>(typeRefs.size());
    for (CtTypeReference<?> typeRef : typeRefs) {
        if (typeRef instanceof CtTypeParameterReference) {
            CtTypeParameterReference typeParamRef = (CtTypeParameterReference) typeRef;
            CtTypeParameter typeParam = typeParamRef.getDeclaration();
            CtFormalTypeDeclarer declarer = typeParam.getTypeParameterDeclarer();
            typeRef = resolveTypeParameter(declarer, typeParamRef, typeParam, typeRef);
        }
        result.add(typeRef);
    }
    return result;
}
Also used : CtTypeParameterReference(spoon.reflect.reference.CtTypeParameterReference) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) ArrayList(java.util.ArrayList)

Example 3 with CtFormalTypeDeclarer

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

the class ClassTypingContext method adaptTypeParameter.

/**
 * adapts `typeParam` to the {@link CtTypeReference}
 * of scope of this {@link ClassTypingContext}
 * In can be {@link CtTypeParameterReference} again - depending actual type arguments of this {@link ClassTypingContext}.
 *
 * @param typeParam to be resolved {@link CtTypeParameter}
 * @return {@link CtTypeReference} or {@link CtTypeParameterReference} adapted to scope of this {@link ClassTypingContext}
 *  or null if `typeParam` cannot be adapted to target `scope`
 */
@Override
protected CtTypeReference<?> adaptTypeParameter(CtTypeParameter typeParam) {
    if (typeParam == null) {
        throw new SpoonException("You cannot adapt a null type parameter.");
    }
    CtFormalTypeDeclarer declarer = typeParam.getTypeParameterDeclarer();
    if ((declarer instanceof CtType<?>) == false) {
        return null;
    }
    // get the actual type argument values for the declarer of `typeParam`
    List<CtTypeReference<?>> actualTypeArguments = resolveActualTypeArgumentsOf(((CtType<?>) declarer).getReference());
    if (actualTypeArguments == null) {
        if (enclosingClassTypingContext != null) {
            // try to adapt parameter using enclosing class typing context
            return enclosingClassTypingContext.adaptType(typeParam);
        }
        return null;
    }
    return getValue(actualTypeArguments, typeParam, declarer);
}
Also used : CtType(spoon.reflect.declaration.CtType) SpoonException(spoon.SpoonException) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) CtTypeReference(spoon.reflect.reference.CtTypeReference)

Example 4 with CtFormalTypeDeclarer

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

the class CtTypeParameterTest method getTypeParamIdentification.

private String getTypeParamIdentification(CtTypeParameter typeParam) {
    String result = "<" + typeParam.getSimpleName() + ">";
    CtFormalTypeDeclarer l_decl = typeParam.getParent(CtFormalTypeDeclarer.class);
    if (l_decl instanceof CtType) {
        return ((CtType) l_decl).getQualifiedName() + result;
    }
    if (l_decl instanceof CtExecutable) {
        CtExecutable exec = (CtExecutable) l_decl;
        if (exec instanceof CtMethod) {
            result = exec.getSignature() + result;
        }
        return exec.getParent(CtType.class).getQualifiedName() + "#" + result;
    }
    throw new AssertionError();
}
Also used : CtType(spoon.reflect.declaration.CtType) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) CtExecutable(spoon.reflect.declaration.CtExecutable) CtMethod(spoon.reflect.declaration.CtMethod)

Example 5 with CtFormalTypeDeclarer

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

the class MethodTypingContext method adaptTypeParameter.

/**
 * Adapts `typeParam` to the {@link CtTypeReference}
 * of scope of this {@link MethodTypingContext}
 * In can be {@link CtTypeParameterReference} again - depending actual type arguments of this {@link MethodTypingContext}.
 *
 * @param typeParam to be resolved {@link CtTypeParameter}
 * @return {@link CtTypeReference} or {@link CtTypeParameterReference} adapted to scope of this {@link MethodTypingContext}
 *  or null if `typeParam` cannot be adapted to target `scope`
 */
@Override
protected CtTypeReference<?> adaptTypeParameter(CtTypeParameter typeParam) {
    CtFormalTypeDeclarer typeParamDeclarer = typeParam.getTypeParameterDeclarer();
    if (typeParamDeclarer instanceof CtType<?>) {
        return getEnclosingGenericTypeAdapter().adaptType(typeParam);
    }
    // only method to method or constructor to constructor can be adapted
    if (typeParamDeclarer instanceof CtMethod<?>) {
        if ((scopeMethod instanceof CtMethod<?>) == false) {
            return null;
        }
    } else if (typeParamDeclarer instanceof CtConstructor<?>) {
        if ((scopeMethod instanceof CtConstructor<?>) == false) {
            return null;
        }
    } else {
        throw new SpoonException("Unexpected type parameter declarer");
    }
    /*
		 *
		 * Two methods or constructors M and N have the same type parameters if both of the following are true:
		 * 1) M and N have same number of type parameters (possibly zero).
		 * 2) Where A1, ..., An are the type parameters of M and B1, ..., Bn are the type parameters of N, let T=[B1:=A1, ..., Bn:=An].
		 * Then, for all i (1 ≤ i ≤ n), the bound of Ai is the same type as T applied to the bound of Bi.
		 */
    if (hasSameMethodFormalTypeParameters(typeParamDeclarer) == false) {
        // the methods formal type parameters are different. We cannot adapt such parameters
        return null;
    }
    int typeParamPosition = typeParamDeclarer.getFormalCtTypeParameters().indexOf(typeParam);
    return actualTypeArguments.get(typeParamPosition);
}
Also used : CtType(spoon.reflect.declaration.CtType) SpoonException(spoon.SpoonException) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) CtMethod(spoon.reflect.declaration.CtMethod)

Aggregations

CtFormalTypeDeclarer (spoon.reflect.declaration.CtFormalTypeDeclarer)6 CtType (spoon.reflect.declaration.CtType)4 CtMethod (spoon.reflect.declaration.CtMethod)3 CtTypeParameter (spoon.reflect.declaration.CtTypeParameter)3 CtTypeReference (spoon.reflect.reference.CtTypeReference)3 SpoonException (spoon.SpoonException)2 CtExecutable (spoon.reflect.declaration.CtExecutable)2 ArrayList (java.util.ArrayList)1 CtElement (spoon.reflect.declaration.CtElement)1 CtTypeMember (spoon.reflect.declaration.CtTypeMember)1 CtExecutableReference (spoon.reflect.reference.CtExecutableReference)1 CtTypeParameterReference (spoon.reflect.reference.CtTypeParameterReference)1