use of spoon.reflect.reference.CtReference in project spoon by INRIA.
the class CtElementPathBuilder method fromElement.
/**
* Build path to a CtElement el, from one of its parent.
*
* @throws CtPathException is thrown when root is not a parent of el.
*
* @param el : the element to which the CtPath leads to
* @param root : Starting point of the CtPath
* @return CtPath from root to el
*/
public CtPath fromElement(CtElement el, CtElement root) throws CtPathException {
CtPathImpl path = new CtPathImpl();
CtElement cur = el;
while (cur != root) {
CtElement parent = cur.getParent();
CtRole role = cur.getRoleInParent();
if (role == null) {
throw new CtPathException();
}
RoleHandler roleHandler = RoleHandlerHelper.getOptionalRoleHandler(parent.getClass(), role);
if (roleHandler == null) {
throw new CtPathException();
}
CtPathElement pathElement = new CtRolePathElement(role);
switch(roleHandler.getContainerKind()) {
case SINGLE:
break;
case LIST:
// Element needs to be differentiated from its brothers
List list = roleHandler.asList(parent);
// Assumes that List's order is deterministic.
// Can't be replaced by list.indexOf(cur)
// Because objects must be the same (and not just equals)
int index = 0;
for (Object o : list) {
if (o == cur) {
break;
}
index++;
}
pathElement.addArgument("index", index + "");
break;
case SET:
String name;
if (cur instanceof CtNamedElement) {
name = ((CtNamedElement) cur).getSimpleName();
} else if (cur instanceof CtReference) {
name = ((CtReference) cur).getSimpleName();
} else {
throw new CtPathException();
}
pathElement.addArgument("name", name);
break;
case MAP:
Map map = roleHandler.asMap(parent);
String key = null;
for (Object o : map.keySet()) {
if (map.get(o) == cur) {
key = (String) o;
break;
}
}
if (key == null) {
throw new CtPathException();
} else {
pathElement.addArgument("key", key);
}
break;
}
cur = parent;
path.addFirst(pathElement);
}
return path;
}
use of spoon.reflect.reference.CtReference in project spoon by INRIA.
the class ContextBuilder method getVariableDeclaration.
@SuppressWarnings("unchecked")
private <T, U extends CtVariable<T>> U getVariableDeclaration(final String name, final Class<U> clazz) {
final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
final ClassFactory classFactory = jdtTreeBuilder.getFactory().Class();
final InterfaceFactory interfaceFactory = jdtTreeBuilder.getFactory().Interface();
final FieldFactory fieldFactory = jdtTreeBuilder.getFactory().Field();
final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
final Environment environment = jdtTreeBuilder.getFactory().getEnvironment();
// there is some extra work to do if we are looking for CtFields (and subclasses)
final boolean lookingForFields = clazz == null || coreFactory.createField().getClass().isAssignableFrom(clazz);
// try to find the variable on stack beginning with the most recent element
for (final ASTPair astPair : stack) {
// the variable may have been declared directly by one of these elements
final ScopeRespectingVariableScanner<U> scanner = new ScopeRespectingVariableScanner(name, clazz);
astPair.element.accept(scanner);
if (scanner.getResult() != null) {
return scanner.getResult();
}
// the variable may have been declared in a super class/interface
if (lookingForFields && astPair.node instanceof TypeDeclaration) {
final TypeDeclaration nodeDeclaration = (TypeDeclaration) astPair.node;
final Deque<ReferenceBinding> referenceBindings = new ArrayDeque<>();
// add super class if any
if (nodeDeclaration.superclass != null && nodeDeclaration.superclass.resolvedType instanceof ReferenceBinding) {
referenceBindings.push((ReferenceBinding) nodeDeclaration.superclass.resolvedType);
}
// add interfaces if any
if (nodeDeclaration.superInterfaces != null) {
for (final TypeReference tr : nodeDeclaration.superInterfaces) {
if (tr.resolvedType instanceof ReferenceBinding) {
referenceBindings.push((ReferenceBinding) tr.resolvedType);
}
}
}
while (!referenceBindings.isEmpty()) {
final ReferenceBinding referenceBinding = referenceBindings.pop();
for (final FieldBinding fieldBinding : referenceBinding.fields()) {
if (name.equals(new String(fieldBinding.readableName()))) {
final String qualifiedNameOfParent = new String(referenceBinding.readableName());
final CtType parentOfField = referenceBinding.isClass() ? classFactory.create(qualifiedNameOfParent) : interfaceFactory.create(qualifiedNameOfParent);
U field = (U) fieldFactory.create(parentOfField, EnumSet.noneOf(ModifierKind.class), referenceBuilder.getTypeReference(fieldBinding.type), name);
return field.setExtendedModifiers(JDTTreeBuilderQuery.getModifiers(fieldBinding.modifiers, true, false));
}
}
// add super class if any
final ReferenceBinding superclass = referenceBinding.superclass();
if (superclass != null) {
referenceBindings.push(superclass);
}
// add interfaces if any
final ReferenceBinding[] interfaces = referenceBinding.superInterfaces();
if (interfaces != null) {
for (ReferenceBinding rb : interfaces) {
referenceBindings.push(rb);
}
}
}
}
}
// the variable may have been imported statically from another class/interface
if (lookingForFields) {
final CtReference potentialReferenceToField = referenceBuilder.getDeclaringReferenceFromImports(name.toCharArray());
if (potentialReferenceToField != null && potentialReferenceToField instanceof CtTypeReference) {
final CtTypeReference typeReference = (CtTypeReference) potentialReferenceToField;
try {
final Class classOfType = typeReference.getActualClass();
if (classOfType != null) {
final CtType declaringTypeOfField = typeReference.isInterface() ? interfaceFactory.get(classOfType) : classFactory.get(classOfType);
final CtField field = declaringTypeOfField.getField(name);
if (field != null) {
return (U) field;
}
}
} catch (final SpoonClassNotFoundException scnfe) {
// field that has been imported statically from another class (or interface).
if (environment.getNoClasspath()) {
// assume a constant value according to JLS.
if (name.toUpperCase().equals(name)) {
final CtType parentOfField = classFactory.create(typeReference.getQualifiedName());
// it is the best thing we can do
final CtField field = coreFactory.createField();
field.setParent(parentOfField);
field.setSimpleName(name);
// it is the best thing we can do
field.setType(typeFactory.nullType());
return (U) field;
}
}
}
}
}
return null;
}
use of spoon.reflect.reference.CtReference in project spoon by INRIA.
the class JDTTreeBuilder method visit.
@Override
public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) {
if (skipTypeInAnnotation) {
return true;
}
if (context.stack.peekFirst().node instanceof UnionTypeReference) {
if (singleTypeReference.resolvedType == null) {
CtTypeReference typeReference = factory.Type().createReference(singleTypeReference.toString());
CtReference ref = references.getDeclaringReferenceFromImports(singleTypeReference.getLastToken());
references.setPackageOrDeclaringType(typeReference, ref);
context.enter(typeReference, singleTypeReference);
} else {
context.enter(references.<Throwable>getTypeReference(singleTypeReference.resolvedType), singleTypeReference);
}
return true;
} else if (context.stack.peekFirst().element instanceof CtCatch) {
context.enter(helper.createCatchVariable(singleTypeReference), singleTypeReference);
return true;
}
context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(singleTypeReference, scope)), singleTypeReference);
return true;
}
use of spoon.reflect.reference.CtReference in project spoon by INRIA.
the class JDTTreeBuilderHelper method createFieldAccessNoClasspath.
/**
* In no classpath mode, when we build a field access, we have a binding typed by ProblemBinding.
* This binding doesn't contain all information but we can get some of them.
*
* @param singleNameReference
* Used to get the problem binding of the field access and the name of the declaring type.
* @return a field access.
*/
<T> CtFieldAccess<T> createFieldAccessNoClasspath(SingleNameReference singleNameReference) {
CtFieldAccess<T> va;
if (isLhsAssignment(jdtTreeBuilder.getContextBuilder(), singleNameReference)) {
va = jdtTreeBuilder.getFactory().Core().createFieldWrite();
} else {
va = jdtTreeBuilder.getFactory().Core().createFieldRead();
}
va.setVariable(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference((ProblemBinding) singleNameReference.binding));
final CtReference declaring = jdtTreeBuilder.getReferencesBuilder().getDeclaringReferenceFromImports(singleNameReference.token);
if (declaring instanceof CtTypeReference && va.getVariable() != null) {
final CtTypeReference<Object> declaringRef = (CtTypeReference<Object>) declaring;
va.setTarget(jdtTreeBuilder.getFactory().Code().createTypeAccess(declaringRef));
va.getVariable().setDeclaringType(declaringRef);
va.getVariable().setStatic(true);
}
return va;
}
use of spoon.reflect.reference.CtReference 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