use of spoon.reflect.reference.CtTypeReference in project spoon by INRIA.
the class JDTTreeBuilderHelper method createCatchVariable.
/**
* Creates a catch variable from a type reference.
*
* @param typeReference
* Correspond to the exception type declared in the catch.
* @return a catch variable.
*/
CtCatchVariable<Throwable> createCatchVariable(TypeReference typeReference) {
final Argument jdtCatch = (Argument) jdtTreeBuilder.getContextBuilder().stack.peekFirst().node;
final Set<CtExtendedModifier> modifiers = getModifiers(jdtCatch.modifiers, false, false);
CtCatchVariable<Throwable> result = jdtTreeBuilder.getFactory().Core().createCatchVariable();
result.<CtCatchVariable>setSimpleName(CharOperation.charToString(jdtCatch.name)).setExtendedModifiers(modifiers);
if (typeReference instanceof UnionTypeReference) {
// do not set type of variable yet. It will be initialized later by visit of multiple types. Each call then ADDs one type
return result;
} else {
CtTypeReference ctTypeReference = jdtTreeBuilder.getReferencesBuilder().<Throwable>getTypeReference(typeReference.resolvedType);
return result.<CtCatchVariable>setType(ctTypeReference);
}
}
use of spoon.reflect.reference.CtTypeReference in project spoon by INRIA.
the class JDTTreeBuilderHelper method createType.
/**
* Creates a class, an enum, an interface or a annotation type.
*
* @return a type.
*/
CtType<?> createType(TypeDeclaration typeDeclaration) {
CtType<?> type;
if ((typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0) {
type = jdtTreeBuilder.getFactory().Core().<java.lang.annotation.Annotation>createAnnotationType();
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccEnum) != 0) {
type = jdtTreeBuilder.getFactory().Core().createEnum();
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccInterface) != 0) {
type = jdtTreeBuilder.getFactory().Core().createInterface();
} else {
type = jdtTreeBuilder.getFactory().Core().createClass();
}
jdtTreeBuilder.getContextBuilder().enter(type, typeDeclaration);
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
final CtTypeReference superInterface = jdtTreeBuilder.references.buildTypeReference(ref, null);
type.addSuperInterface(superInterface);
}
}
if (type instanceof CtClass) {
if (typeDeclaration.superclass != null) {
((CtClass) type).setSuperclass(jdtTreeBuilder.references.buildTypeReference(typeDeclaration.superclass, typeDeclaration.scope));
}
if (typeDeclaration.binding.isAnonymousType() || (typeDeclaration.binding instanceof LocalTypeBinding && typeDeclaration.binding.enclosingMethod() != null)) {
type.setSimpleName(computeAnonymousName(typeDeclaration.binding.constantPoolName()));
} else {
type.setSimpleName(new String(typeDeclaration.name));
}
} else {
type.setSimpleName(new String(typeDeclaration.name));
}
// Setting modifiers
type.setExtendedModifiers(getModifiers(typeDeclaration.modifiers, false, false));
return type;
}
use of spoon.reflect.reference.CtTypeReference in project spoon by INRIA.
the class JDTTreeBuilderHelper method createVariableAccessNoClasspath.
/**
* Analyzes if {@code singleNameReference} points to a {@link CtVariable} visible in current
* scope and, if existent, returns its corresponding {@link CtVariableAccess}. Returns
* {@code null} if {@code singleNameReference} could not be resolved as variable access. Since
* we are in noclasspath mode this function may also returns {@code null} if
* {@code singleNameReference} points to a variable declared by an unknown class.
*
* @param singleNameReference
* The potential variable access.
* @return A {@link CtVariableAccess} if {@code singleNameReference} points to a variable
* visible in current scope, {@code null} otherwise.
*/
<T> CtVariableAccess<T> createVariableAccessNoClasspath(SingleNameReference singleNameReference) {
final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
final ExecutableFactory executableFactory = jdtTreeBuilder.getFactory().Executable();
final ContextBuilder contextBuilder = jdtTreeBuilder.getContextBuilder();
final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
final PositionBuilder positionBuilder = jdtTreeBuilder.getPositionBuilder();
final String name = CharOperation.charToString(singleNameReference.token);
final CtVariable<T> variable = contextBuilder.getVariableDeclaration(name);
if (variable == null) {
return null;
}
final CtVariableReference<T> variableReference;
final CtVariableAccess<T> variableAccess;
if (variable instanceof CtParameter) {
// create variable of concrete type to avoid type casting while calling methods
final CtParameterReference<T> parameterReference = coreFactory.createParameterReference();
if (variable.getParent() instanceof CtLambda) {
// nothing
} else {
// Unfortunately, we can not use `variable.getReference()` here as some parent
// references (in terms of Java objects) have not been set up yet. Thus, we need to
// create the required parameter reference by our own.
// Since the given parameter has not been declared in a lambda expression it must
// have been declared by a method/constructor.
final CtExecutable executable = (CtExecutable) variable.getParent();
// create list of executable's parameter types
final List<CtTypeReference<?>> parameterTypesOfExecutable = new ArrayList<>();
@SuppressWarnings("unchecked") final List<CtParameter<?>> parametersOfExecutable = executable.getParameters();
for (CtParameter<?> parameter : parametersOfExecutable) {
parameterTypesOfExecutable.add(parameter.getType() != null ? parameter.getType().clone() : // it's the best match :(
typeFactory.OBJECT.clone());
}
// find executable's corresponding jdt element
AbstractMethodDeclaration executableJDT = null;
for (final ASTPair astPair : contextBuilder.stack) {
if (astPair.element == executable) {
executableJDT = (AbstractMethodDeclaration) astPair.node;
}
}
assert executableJDT != null;
// create a reference to executable's declaring class
final CtTypeReference declaringReferenceOfExecutable = // available
executableJDT.binding == null ? coreFactory.createTypeReference() : referenceBuilder.getTypeReference(executableJDT.binding.declaringClass);
// If executable is a constructor, `executable.getType()` returns null since the
// parent is not available yet. Fortunately, however, the return type of a
// constructor is its declaring class which, in our case, is already available with
// declaringReferenceOfExecutable.
CtTypeReference executableTypeReference = executable instanceof CtConstructor ? // indirectly sets the parent of `rt` and, thus, may break the AST!
declaringReferenceOfExecutable.clone() : executable.getType().clone();
}
variableReference = parameterReference;
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createVariableWrite() : coreFactory.<T>createVariableRead();
} else if (variable instanceof CtField) {
variableReference = variable.getReference();
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createFieldWrite() : coreFactory.<T>createFieldRead();
} else {
// CtLocalVariable, CtCatchVariable, ...
variableReference = variable.getReference();
variableAccess = isLhsAssignment(contextBuilder, singleNameReference) ? coreFactory.<T>createVariableWrite() : coreFactory.<T>createVariableRead();
}
variableReference.setSimpleName(name);
variableReference.setPosition(positionBuilder.buildPosition(singleNameReference.sourceStart(), singleNameReference.sourceEnd()));
variableAccess.setVariable(variableReference);
return variableAccess;
}
use of spoon.reflect.reference.CtTypeReference in project spoon by INRIA.
the class ReferenceBuilder method getExecutableReference.
<T> CtExecutableReference<T> getExecutableReference(MessageSend messageSend) {
if (messageSend.binding != null) {
return getExecutableReference(messageSend.binding);
}
CtExecutableReference<T> ref = jdtTreeBuilder.getFactory().Core().createExecutableReference();
ref.setSimpleName(CharOperation.charToString(messageSend.selector));
ref.setType(this.<T>getTypeReference(messageSend.expectedType()));
if (messageSend.receiver.resolvedType == null) {
// It is crisis dude! static context, we don't have much more information.
if (messageSend.receiver instanceof SingleNameReference) {
ref.setDeclaringType(jdtTreeBuilder.getHelper().createTypeAccessNoClasspath((SingleNameReference) messageSend.receiver).getAccessedType());
} else if (messageSend.receiver instanceof QualifiedNameReference) {
ref.setDeclaringType(jdtTreeBuilder.getHelper().createTypeAccessNoClasspath((QualifiedNameReference) messageSend.receiver).getAccessedType());
}
} else {
ref.setDeclaringType(getTypeReference(messageSend.receiver.resolvedType));
}
if (messageSend.arguments != null) {
final List<CtTypeReference<?>> parameters = new ArrayList<>();
for (Expression expression : messageSend.arguments) {
parameters.add(getTypeReference(expression.resolvedType));
}
ref.setParameters(parameters);
}
return ref;
}
use of spoon.reflect.reference.CtTypeReference in project spoon by INRIA.
the class ReferenceBuilder method getTypeReference.
@SuppressWarnings("unchecked")
<T> CtTypeReference<T> getTypeReference(TypeBinding binding) {
if (binding == null) {
return null;
}
CtTypeReference<?> ref = null;
if (binding instanceof RawTypeBinding) {
ref = getTypeReference(((ParameterizedTypeBinding) binding).genericType());
} else if (binding instanceof ParameterizedTypeBinding) {
if (binding.actualType() != null && binding.actualType() instanceof LocalTypeBinding) {
// When we define a nested class in a method and when the enclosing class of this method
// is a parameterized type binding, JDT give a ParameterizedTypeBinding for the nested class
// and hide the real class in actualType().
ref = getTypeReference(binding.actualType());
} else {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
this.exploringParameterizedBindings.put(binding, ref);
if (binding.isAnonymousType()) {
ref.setSimpleName("");
} else {
ref.setSimpleName(String.valueOf(binding.sourceName()));
if (binding.enclosingType() != null) {
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
} else {
ref.setPackage(getPackageReference(binding.getPackage()));
}
}
}
if (binding.actualType() instanceof MissingTypeBinding) {
ref = getTypeReference(binding.actualType());
}
if (((ParameterizedTypeBinding) binding).arguments != null) {
for (TypeBinding b : ((ParameterizedTypeBinding) binding).arguments) {
if (bindingCache.containsKey(b)) {
ref.addActualTypeArgument(getCtCircularTypeReference(b));
} else {
if (!this.exploringParameterizedBindings.containsKey(b)) {
this.exploringParameterizedBindings.put(b, null);
CtTypeReference typeRefB = getTypeReference(b);
this.exploringParameterizedBindings.put(b, typeRefB);
ref.addActualTypeArgument(typeRefB);
} else {
CtTypeReference typeRefB = this.exploringParameterizedBindings.get(b);
if (typeRefB != null) {
ref.addActualTypeArgument(typeRefB.clone());
}
}
}
}
}
} else if (binding instanceof MissingTypeBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
ref.setSimpleName(new String(binding.sourceName()));
ref.setPackage(getPackageReference(binding.getPackage()));
if (!this.jdtTreeBuilder.getContextBuilder().ignoreComputeImports) {
final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
if (declaring instanceof CtPackageReference) {
ref.setPackage((CtPackageReference) declaring);
} else if (declaring instanceof CtTypeReference) {
ref.setDeclaringType((CtTypeReference) declaring);
}
}
} else if (binding instanceof BinaryTypeBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
if (binding.enclosingType() != null) {
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
} else {
ref.setPackage(getPackageReference(binding.getPackage()));
}
ref.setSimpleName(new String(binding.sourceName()));
} else if (binding instanceof TypeVariableBinding) {
boolean oldBounds = bounds;
if (binding instanceof CaptureBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();
bounds = true;
} else {
TypeVariableBinding typeParamBinding = (TypeVariableBinding) binding;
ReferenceBinding superClass = typeParamBinding.superclass;
ReferenceBinding[] superInterfaces = typeParamBinding.superInterfaces();
CtTypeReference refSuperClass = null;
// superClass.superclass() is null if it's java.lang.Object
if (superClass != null && !(superClass.superclass() == null)) {
// to conserve the same behavior as JavaReflectionTreeBuilder
if (!(superClass instanceof ParameterizedTypeBinding) || !this.exploringParameterizedBindings.containsKey(superClass)) {
refSuperClass = this.getTypeReference(superClass);
}
// if the type parameter has a super interface, then we'll get it too, as a superclass
// type parameter can only extends an interface or a class, so we don't make the distinction
// in Spoon. Moreover we can only have one extends in a type parameter.
} else if (superInterfaces != null && superInterfaces.length == 1) {
refSuperClass = this.getTypeReference(superInterfaces[0]);
}
ref = this.jdtTreeBuilder.getFactory().Core().createTypeParameterReference();
ref.setSimpleName(new String(binding.sourceName()));
if (refSuperClass != null) {
((CtTypeParameterReference) ref).addBound(refSuperClass);
}
}
TypeVariableBinding b = (TypeVariableBinding) binding;
if (bounds) {
if (b instanceof CaptureBinding && ((CaptureBinding) b).wildcard != null) {
bounds = oldBounds;
return getTypeReference(((CaptureBinding) b).wildcard);
} else if (b.superclass != null && b.firstBound == b.superclass) {
bounds = false;
bindingCache.put(binding, ref);
((CtTypeParameterReference) ref).setBoundingType(getTypeReference(b.superclass));
bounds = oldBounds;
}
}
if (bounds && b.superInterfaces != null && b.superInterfaces != Binding.NO_SUPERINTERFACES) {
bounds = false;
bindingCache.put(binding, ref);
List<CtTypeReference<?>> bounds = new ArrayList<>();
CtTypeParameterReference typeParameterReference = (CtTypeParameterReference) ref;
if (!(typeParameterReference.isDefaultBoundingType())) {
// if it's object we can ignore it
bounds.add(typeParameterReference.getBoundingType());
}
for (ReferenceBinding superInterface : b.superInterfaces) {
bounds.add(getTypeReference(superInterface));
}
((CtTypeParameterReference) ref).setBoundingType(this.jdtTreeBuilder.getFactory().Type().createIntersectionTypeReferenceWithBounds(bounds));
}
if (binding instanceof CaptureBinding) {
bounds = false;
}
} else if (binding instanceof BaseTypeBinding) {
String name = new String(binding.sourceName());
ref = basestypes.get(name);
if (ref == null) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
ref.setSimpleName(name);
basestypes.put(name, ref);
} else {
ref = ref == null ? ref : ref.clone();
}
} else if (binding instanceof WildcardBinding) {
WildcardBinding wildcardBinding = (WildcardBinding) binding;
ref = this.jdtTreeBuilder.getFactory().Core().createWildcardReference();
if (wildcardBinding.boundKind == Wildcard.SUPER && ref instanceof CtTypeParameterReference) {
((CtTypeParameterReference) ref).setUpper(false);
}
if (wildcardBinding.bound != null && ref instanceof CtTypeParameterReference) {
if (bindingCache.containsKey(wildcardBinding.bound)) {
((CtTypeParameterReference) ref).setBoundingType(getCtCircularTypeReference(wildcardBinding.bound));
} else {
((CtTypeParameterReference) ref).setBoundingType(getTypeReference(((WildcardBinding) binding).bound));
}
}
} else if (binding instanceof LocalTypeBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
if (binding.isAnonymousType()) {
ref.setSimpleName(JDTTreeBuilderHelper.computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
ref.setDeclaringType(getTypeReference((binding.enclosingType())));
} else {
ref.setSimpleName(new String(binding.sourceName()));
if (((LocalTypeBinding) binding).enclosingMethod == null && binding.enclosingType() != null && binding.enclosingType() instanceof LocalTypeBinding) {
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
} else if (binding.enclosingMethod() != null) {
ref.setSimpleName(JDTTreeBuilderHelper.computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
}
}
} else if (binding instanceof SourceTypeBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
if (binding.isAnonymousType()) {
ref.setSimpleName(JDTTreeBuilderHelper.computeAnonymousName(((SourceTypeBinding) binding).constantPoolName()));
ref.setDeclaringType(getTypeReference((binding.enclosingType())));
} else {
ref.setSimpleName(new String(binding.sourceName()));
if (binding.enclosingType() != null) {
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
} else {
ref.setPackage(getPackageReference(binding.getPackage()));
}
// if(((SourceTypeBinding) binding).typeVariables!=null &&
// ((SourceTypeBinding) binding).typeVariables.length>0){
// for (TypeBinding b : ((SourceTypeBinding)
// binding).typeVariables) {
// ref.getActualTypeArguments().add(getTypeReference(b));
// }
// }
}
} else if (binding instanceof ArrayBinding) {
CtArrayTypeReference<Object> arrayref;
arrayref = this.jdtTreeBuilder.getFactory().Core().createArrayTypeReference();
ref = arrayref;
for (int i = 1; i < binding.dimensions(); i++) {
CtArrayTypeReference<Object> tmp = this.jdtTreeBuilder.getFactory().Core().createArrayTypeReference();
arrayref.setComponentType(tmp);
arrayref = tmp;
}
arrayref.setComponentType(getTypeReference(binding.leafComponentType()));
} else if (binding instanceof PolyTypeBinding) {
// JDT can't resolve the type of this binding and we only have a string.
// In this case, we return a type Object because we can't know more about it.
ref = this.jdtTreeBuilder.getFactory().Type().objectType();
} else if (binding instanceof ProblemReferenceBinding) {
// Spoon is able to analyze also without the classpath
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
ref.setSimpleName(new String(binding.readableName()));
final CtReference declaring = this.getDeclaringReferenceFromImports(binding.sourceName());
setPackageOrDeclaringType(ref, declaring);
} else if (binding instanceof JDTTreeBuilder.SpoonReferenceBinding) {
ref = this.jdtTreeBuilder.getFactory().Core().createTypeReference();
ref.setSimpleName(new String(binding.sourceName()));
ref.setDeclaringType(getTypeReference(binding.enclosingType()));
} else if (binding instanceof IntersectionTypeBinding18) {
List<CtTypeReference<?>> bounds = new ArrayList<>();
for (ReferenceBinding superInterface : binding.getIntersectingTypes()) {
bounds.add(getTypeReference(superInterface));
}
ref = this.jdtTreeBuilder.getFactory().Type().createIntersectionTypeReferenceWithBounds(bounds);
} else {
throw new RuntimeException("Unknown TypeBinding: " + binding.getClass() + " " + binding);
}
bindingCache.remove(binding);
this.exploringParameterizedBindings.remove(binding);
return (CtTypeReference<T>) ref;
}
Aggregations