use of spoon.SpoonException in project spoon by INRIA.
the class CloneHelper method createRightSet.
private <T extends CtElement> Set<T> createRightSet(Set<T> elements) {
try {
if (elements instanceof TreeSet) {
// we copy the set, incl its comparator
// we may also do this with reflection
Set s = (Set) ((TreeSet) elements).clone();
s.clear();
return s;
} else {
return elements.getClass().newInstance();
}
} catch (InstantiationException | IllegalAccessException e) {
throw new SpoonException(e);
}
}
use of spoon.SpoonException 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);
}
use of spoon.SpoonException in project spoon by INRIA.
the class MethodTypingContext method setExecutableReference.
public MethodTypingContext setExecutableReference(CtExecutableReference<?> execRef) {
if (classTypingContext == null) {
CtTypeReference<?> declaringTypeRef = execRef.getDeclaringType();
if (declaringTypeRef != null) {
classTypingContext = new ClassTypingContext(declaringTypeRef);
}
}
CtExecutable<?> exec = execRef.getExecutableDeclaration();
if (exec == null) {
throw new SpoonException("Cannot create MethodTypingContext from CtExecutable of CtExecutableReference is null");
}
if (exec instanceof CtMethod<?>) {
setMethod((CtMethod<?>) exec);
} else if (exec instanceof CtConstructor<?>) {
setConstructor((CtConstructor<?>) exec);
} else {
throw new SpoonException("Cannot create MethodTypingContext from " + exec.getClass().getName());
}
this.actualTypeArguments = execRef.getActualTypeArguments();
return this;
}
use of spoon.SpoonException in project spoon by INRIA.
the class MethodTypingContext method setMethod.
public MethodTypingContext setMethod(CtMethod<?> method) {
actualTypeArguments = getTypeReferences(method.getFormalCtTypeParameters());
if (classTypingContext != null) {
CtType<?> declType = method.getDeclaringType();
if (declType == null) {
throw new SpoonException("Cannot use method without declaring type as scope of method typing context");
}
if (classTypingContext.getAdaptationScope() != declType) {
// the method is declared in different type. We have to adapt it to required classTypingContext
if (classTypingContext.isSubtypeOf(declType.getReference()) == false) {
throw new SpoonException("Cannot create MethodTypingContext for method declared in different ClassTypingContext");
}
/*
* The method is declared in an supertype of classTypingContext.
* Create virtual scope method by adapting generic types of supertype method to required scope
*/
Factory factory = method.getFactory();
// create new scopeMethod, which is directly used during adaptation of it's parameters
CtMethod<?> adaptedMethod = factory.Core().createMethod();
adaptedMethod.setParent(classTypingContext.getAdaptationScope());
adaptedMethod.setModifiers(method.getModifiers());
adaptedMethod.setSimpleName(method.getSimpleName());
for (CtTypeParameter typeParam : method.getFormalCtTypeParameters()) {
CtTypeParameter newTypeParam = typeParam.clone();
newTypeParam.setSuperclass(adaptTypeForNewMethod(typeParam.getSuperclass()));
adaptedMethod.addFormalCtTypeParameter(newTypeParam);
}
// now the formal type parameters of the scopeMethod are defined, so we can use adaptType of this MethodTypingContext
scopeMethod = adaptedMethod;
for (CtTypeReference<? extends Throwable> thrownType : method.getThrownTypes()) {
adaptedMethod.addThrownType((CtTypeReference<Throwable>) adaptType(thrownType.clone()));
}
// adapt return type
adaptedMethod.setType((CtTypeReference) adaptType(method.getType()));
// adapt parameters
List<CtParameter<?>> adaptedParams = new ArrayList<>(method.getParameters().size());
for (CtParameter<?> parameter : method.getParameters()) {
adaptedParams.add(factory.Executable().createParameter(null, adaptType(parameter.getType()), parameter.getSimpleName()));
}
adaptedMethod.setParameters(adaptedParams);
method = adaptedMethod;
}
}
scopeMethod = method;
return this;
}
use of spoon.SpoonException in project spoon by INRIA.
the class MethodTypingContext method adaptTypeForNewMethod.
private CtTypeReference<?> adaptTypeForNewMethod(CtTypeReference<?> typeRef) {
if (typeRef == null) {
return null;
}
if (typeRef instanceof CtTypeParameterReference) {
CtTypeParameterReference typeParamRef = (CtTypeParameterReference) typeRef;
CtTypeParameter typeParam = typeParamRef.getDeclaration();
if (typeParam == null) {
throw new SpoonException("Declaration of the CtTypeParameter should not be null.");
}
if (typeParam.getTypeParameterDeclarer() instanceof CtExecutable) {
// the parameter is declared in scope of Method or Constructor
return typeRef.clone();
}
}
// it is not type reference of scopeMethod. Adapt it using classTypingContext
return classTypingContext.adaptType(typeRef);
}
Aggregations