use of spoon.reflect.declaration.CtElement 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;
}
use of spoon.reflect.declaration.CtElement 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;
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class ParentFunction method apply.
@Override
public void apply(CtElement input, CtConsumer<Object> outputConsumer) {
if (input == null) {
return;
}
if (includingSelf) {
outputConsumer.accept(input);
}
CtElement parent = input;
CtModule topLevel = input.getFactory().getModel().getUnnamedModule();
while (parent != null && parent != topLevel && query.isTerminated() == false && parent.isParentInitialized()) {
parent = parent.getParent();
outputConsumer.accept(parent);
}
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class PotentialVariableDeclarationFunction method apply.
@Override
public void apply(CtElement input, CtConsumer<Object> outputConsumer) {
isTypeOnTheWay = false;
isInStaticScope = false;
// Search previous siblings for element which may represents the declaration of this local variable
CtQuery siblingsQuery = input.getFactory().createQuery().map(new SiblingsFunction().mode(SiblingsFunction.Mode.PREVIOUS)).select(new TypeFilter<>(CtVariable.class));
if (variableName != null) {
// variable name is defined so we have to search only for variables with that name
siblingsQuery = siblingsQuery.select(new NamedElementFilter<>(CtNamedElement.class, variableName));
}
CtElement scopeElement = input;
// Search input and then all parents until first CtPackage for element which may represents the declaration of this local variable
while (scopeElement != null && !(scopeElement instanceof CtPackage) && scopeElement.isParentInitialized()) {
CtElement parent = scopeElement.getParent();
if (parent instanceof CtType<?>) {
isTypeOnTheWay = true;
// visit each CtField of `parent` CtType
CtQuery q = parent.map(new AllTypeMembersFunction(CtField.class));
q.forEach((CtField<?> field) -> {
if (isInStaticScope && field.hasModifier(ModifierKind.STATIC) == false) {
/*
* the variable reference is used in static scope,
* but the field is not static - ignore it
*/
return;
}
// else send field as potential variable declaration
if (sendToOutput(field, outputConsumer)) {
// and terminate the internal query q if outer query is already terminated
q.terminate();
}
});
if (query.isTerminated()) {
return;
}
} else if (parent instanceof CtBodyHolder || parent instanceof CtStatementList) {
// visit all previous CtVariable siblings of scopeElement element in parent BodyHolder or Statement list
siblingsQuery.setInput(scopeElement).forEach(outputConsumer);
if (query.isTerminated()) {
return;
}
// visit parameters of CtCatch and CtExecutable (method, lambda)
if (parent instanceof CtCatch) {
CtCatch ctCatch = (CtCatch) parent;
if (sendToOutput(ctCatch.getParameter(), outputConsumer)) {
return;
}
} else if (parent instanceof CtExecutable) {
CtExecutable<?> exec = (CtExecutable<?>) parent;
for (CtParameter<?> param : exec.getParameters()) {
if (sendToOutput(param, outputConsumer)) {
return;
}
}
}
}
if (parent instanceof CtModifiable) {
isInStaticScope = isInStaticScope || ((CtModifiable) parent).hasModifier(ModifierKind.STATIC);
}
scopeElement = parent;
}
}
use of spoon.reflect.declaration.CtElement in project spoon by INRIA.
the class CtRolePathElement method getElements.
@Override
public Collection<CtElement> getElements(Collection<CtElement> roots) {
Collection<CtElement> matchs = new LinkedList<>();
for (CtElement root : roots) {
RoleHandler roleHandler = RoleHandlerHelper.getOptionalRoleHandler(root.getClass(), getRole());
if (roleHandler != null) {
switch(roleHandler.getContainerKind()) {
case SINGLE:
if (roleHandler.getValue(root) != null) {
matchs.add(roleHandler.getValue(root));
}
break;
case LIST:
if (getArguments().containsKey("index")) {
int index = Integer.parseInt(getArguments().get("index"));
if (index < roleHandler.asList(root).size()) {
matchs.add((CtElement) roleHandler.asList(root).get(index));
}
} else {
matchs.addAll(roleHandler.asList(root));
}
break;
case SET:
if (getArguments().containsKey("name")) {
String name = getArguments().get("name");
try {
CtElement match = getFromSet(roleHandler.asSet(root), name);
if (match != null) {
matchs.add(match);
}
} catch (CtPathException e) {
// System.err.println("[ERROR] Element not found for name: " + name);
// No element found for name.
}
} else {
matchs.addAll(roleHandler.asSet(root));
}
break;
case MAP:
if (getArguments().containsKey("key")) {
String name = getArguments().get("key");
if (roleHandler.asMap(root).containsKey(name)) {
matchs.add((CtElement) roleHandler.asMap(root).get(name));
}
} else {
Map<String, CtElement> map = roleHandler.asMap(root);
matchs.addAll(map.values());
}
break;
}
}
}
return matchs;
}
Aggregations