use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class Refactoring method copyType.
/**
* See doc in {@link CtType#copyType()}
*/
public static CtType<?> copyType(final CtType<?> type) {
CtType<?> clone = type.clone();
String tentativeTypeName = type.getSimpleName() + "Copy";
while (type.getFactory().Type().get(type.getPackage().getQualifiedName() + "." + tentativeTypeName) != null) {
tentativeTypeName += "X";
}
final String cloneTypeName = tentativeTypeName;
clone.setSimpleName(cloneTypeName);
type.getPackage().addType(clone);
new CtScanner() {
@Override
public <T> void visitCtTypeReference(CtTypeReference<T> reference) {
if (reference.getDeclaration() == null) {
return;
}
if (reference.getDeclaration() == type) {
reference.setSimpleName(cloneTypeName);
}
if (reference.getDeclaration() != clone) {
throw new SpoonException("post condition broken " + reference);
}
super.visitCtTypeReference(reference);
}
@Override
public <T> void visitCtExecutableReference(CtExecutableReference<T> reference) {
CtExecutable<T> declaration = reference.getDeclaration();
if (declaration == null) {
return;
}
if (declaration.hasParent(type)) {
reference.getDeclaringType().setSimpleName(cloneTypeName);
}
if (!reference.getDeclaration().hasParent(clone)) {
throw new SpoonException("post condition broken " + reference);
}
super.visitCtExecutableReference(reference);
}
@Override
public <T> void visitCtFieldReference(CtFieldReference<T> reference) {
CtField<T> declaration = reference.getDeclaration();
if (declaration == null) {
return;
}
if (declaration.hasParent(type)) {
reference.getDeclaringType().setSimpleName(cloneTypeName);
}
if (reference.getDeclaration() == null || !reference.getDeclaration().hasParent(clone)) {
throw new SpoonException("post condition broken " + reference);
}
super.visitCtFieldReference(reference);
}
}.scan(clone);
return clone;
}
use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class FilterTest method testFieldAccessFilter.
@Test
public void testFieldAccessFilter() throws Exception {
// also specifies VariableAccessFilter since FieldAccessFilter is only a VariableAccessFilter with additional static typing
CtClass<?> foo = factory.Package().get("spoon.test.filters").getType("Foo");
assertEquals("Foo", foo.getSimpleName());
List<CtNamedElement> elements = foo.getElements(new NamedElementFilter<>(CtNamedElement.class, "i"));
assertEquals(1, elements.size());
CtFieldReference<?> ref = (CtFieldReference<?>) (elements.get(0)).getReference();
List<CtFieldAccess<?>> expressions = foo.getElements(new FieldAccessFilter(ref));
assertEquals(2, expressions.size());
final Factory build = build(FieldAccessFilterTacos.class);
final CtType<FieldAccessFilterTacos> fieldAccessFilterTacos = build.Type().get(FieldAccessFilterTacos.class);
try {
List<CtField> fields = fieldAccessFilterTacos.getElements(new TypeFilter<CtField>(CtField.class));
for (CtField ctField : fields) {
fieldAccessFilterTacos.getElements(new FieldAccessFilter(ctField.getReference()));
}
} catch (NullPointerException e) {
fail("FieldAccessFilter must not throw a NPE.");
}
}
use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class FilterTest method testNameFilterWithGenericType.
@Test
public void testNameFilterWithGenericType() {
// contract: NamedElementFilter of T should only return T elements
Launcher spoon = new Launcher();
spoon.addInputResource("./src/test/java/spoon/test/imports/testclasses/internal4/Constants.java");
spoon.buildModel();
CtType type = spoon.getFactory().Type().get(Constants.class);
List<CtMethod> ctMethods = type.getElements(new NamedElementFilter<>(CtMethod.class, "CONSTANT"));
assertTrue(ctMethods.isEmpty());
List<CtField> ctFields = type.getElements(new NamedElementFilter<>(CtField.class, "CONSTANT"));
assertEquals(1, ctFields.size());
assertTrue(ctFields.get(0) instanceof CtField);
}
use of spoon.reflect.declaration.CtField in project spoon by INRIA.
the class ImportTest method testGetImportKindReturnRightValue.
@Test
public void testGetImportKindReturnRightValue() {
// contract: the importKind is computed based on the reference class type and the boolean isImportAllStaticTypeMembers
final Launcher spoon = new Launcher();
CtType aType = spoon.getFactory().Type().get(Reflection.class);
CtImport ctImport = spoon.getFactory().createImport(aType.getReference());
assertEquals(CtImportKind.TYPE, ctImport.getImportKind());
ctImport = spoon.getFactory().createImport(spoon.getFactory().Type().createWildcardStaticTypeMemberReference(aType.getReference()));
assertEquals(CtImportKind.ALL_STATIC_MEMBERS, ctImport.getImportKind());
ctImport = spoon.getFactory().createImport(((CtMethod) aType.getAllMethods().iterator().next()).getReference());
assertEquals(CtImportKind.METHOD, ctImport.getImportKind());
ctImport = spoon.getFactory().createImport(((CtField) aType.getFields().get(0)).getReference());
assertEquals(CtImportKind.FIELD, ctImport.getImportKind());
ctImport = spoon.getFactory().createImport(aType.getPackage().getReference());
assertEquals(CtImportKind.ALL_TYPES, ctImport.getImportKind());
}
use of spoon.reflect.declaration.CtField 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;
}
Aggregations