use of spoon.reflect.declaration.CtType in project spoon by INRIA.
the class DefaultJavaPrettyPrinter method visitCtThisAccess.
@Override
public <T> void visitCtThisAccess(CtThisAccess<T> thisAccess) {
try {
enterCtExpression(thisAccess);
// we only write qualified this when this is required
// this is good both in fully-qualified mode and in readable (with-imports) mode
// the implicit information is used for analysis (eg are visibility caused by implicit bugs?) but
// not for pretty-printing
CtTypeAccess target = (CtTypeAccess) thisAccess.getTarget();
CtTypeReference targetType = target.getAccessedType();
// readable mode as close as possible to the original code
if (thisAccess.isImplicit()) {
// what the good target is in JDTTreeBuilder
return;
}
// this is shorter (no qualified this), explicit, and less fragile wrt transformation
if (targetType == null || (thisAccess.getParent(CtType.class) != null && thisAccess.getParent(CtType.class).isTopLevel())) {
printer.writeKeyword("this");
// still go through finally block below
return;
}
// this has to come after the implicit test just before
if (targetType.isAnonymous()) {
printer.writeKeyword("this");
return;
}
// complex case of qualifed this
if (!context.currentThis.isEmpty()) {
CtType lastType = context.currentThis.peekFirst().type;
String lastTypeQualifiedName = lastType.getQualifiedName();
String targetTypeQualifiedName = targetType.getQualifiedName();
if (!lastTypeQualifiedName.equals(targetTypeQualifiedName)) {
if (!targetType.isImplicit()) {
visitCtTypeReferenceWithoutGenerics(targetType);
printer.writeSeparator(".");
}
printer.writeKeyword("this");
return;
}
}
// the default super simple case only comes at the end
printer.writeKeyword("this");
} finally {
exitCtExpression(thisAccess);
}
}
use of spoon.reflect.declaration.CtType in project spoon by INRIA.
the class ImportScannerImpl method visitCtInterface.
@Override
public <T> void visitCtInterface(CtInterface<T> intrface) {
addClassImport(intrface.getReference());
for (CtTypeMember t : intrface.getTypeMembers()) {
if (!(t instanceof CtType)) {
continue;
}
addClassImport(((CtType) t).getReference());
}
super.visitCtInterface(intrface);
}
use of spoon.reflect.declaration.CtType in project spoon by INRIA.
the class CtRenameLocalVariableRefactoring method detectNameConflicts.
@Override
protected void detectNameConflicts() {
/*
* There can be these conflicts
* 1) target variable would shadow before declared variable (parameter, localVariable, catchVariable)
* --------------------------------------------------------------------------------------------------
*/
PotentialVariableDeclarationFunction potentialDeclarationFnc = new PotentialVariableDeclarationFunction(newName);
CtVariable<?> var = getTarget().map(potentialDeclarationFnc).first();
if (var != null) {
if (var instanceof CtField) {
/*
* we have found a field of same name.
* It is not problem, because variables can hide field declaration.
* Do nothing - OK
*/
} else if (potentialDeclarationFnc.isTypeOnTheWay()) {
/*
* There is a local class declaration between future variable reference and variable declaration `var`.
* The found variable declaration `var` can be hidden by target variable with newName
* as long as there is no reference to `var` in visibility scope of the target variable.
* So search for such `var` reference now
*/
CtVariableReference<?> shadowedVar = target.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT)).map(new VariableReferenceFunction(var)).first();
if (shadowedVar != null) {
// found variable reference, which would be shadowed by variable after rename.
createNameConflictIssue(var, shadowedVar);
} else {
/*
* there is no local variable reference, which would be shadowed by variable after rename.
* OK
*/
}
} else {
/*
* the found variable is in conflict with target variable with newName
*/
createNameConflictIssue(var);
}
}
/*
* 2) target variable is shadowed by later declared variable
* ---------------------------------------------------------
*/
final QueryDriver queryDriver = new QueryDriver();
getTarget().map(new LocalVariableScopeFunction(queryDriver)).select(new Filter<CtElement>() {
/**
* return true for all CtVariables, which are in conflict
*/
@Override
public boolean matches(CtElement element) {
if (element instanceof CtType<?>) {
CtType<?> localClass = (CtType<?>) element;
// TODO use faster hasField, implemented using map(new AllFieldsFunction()).select(new NameFilter(newName)).first()!=null
Collection<CtFieldReference<?>> fields = localClass.getAllFields();
for (CtFieldReference<?> fieldRef : fields) {
if (newName.equals(fieldRef.getSimpleName())) {
/*
* we have found a local class field, which will shadow input local variable if it's reference is in visibility scope of that field.
* Search for target variable reference in visibility scope of this field.
* If found than we cannot rename target variable to newName, because that reference would be shadowed
*/
queryDriver.ignoreChildrenOf(element);
CtLocalVariableReference<?> shadowedVar = element.map(new LocalVariableReferenceFunction(target)).first();
if (shadowedVar != null) {
createNameConflictIssue(fieldRef.getFieldDeclaration(), shadowedVar);
return true;
}
return false;
}
}
return false;
}
if (element instanceof CtVariable<?>) {
CtVariable<?> variable = (CtVariable<?>) element;
if (newName.equals(variable.getSimpleName()) == false) {
// the variable with different name. Ignore it
return false;
}
// we have found a variable with new name
if (variable instanceof CtField) {
throw new SpoonException("This should not happen. The children of local class which contains a field with new name should be skipped!");
}
if (variable instanceof CtCatchVariable || variable instanceof CtLocalVariable || variable instanceof CtParameter) {
/*
* we have found a catch variable or local variable or parameter with new name.
*/
if (queryDriver.isInContextOfLocalClass()) {
/*
* We are in context of local class.
* This variable would shadow input local variable after rename
* so we cannot rename if there exist a local variable reference in variable visibility scope.
*/
queryDriver.ignoreChildrenOf(variable.getParent());
CtQueryable searchScope;
if (variable instanceof CtLocalVariable) {
searchScope = variable.map(new SiblingsFunction().includingSelf(true).mode(Mode.NEXT));
} else {
searchScope = variable.getParent();
}
CtLocalVariableReference<?> shadowedVar = searchScope.map(new LocalVariableReferenceFunction(target)).first();
if (shadowedVar != null) {
// found local variable reference, which would be shadowed by variable after rename.
createNameConflictIssue(variable, shadowedVar);
return true;
}
// there is no local variable reference, which would be shadowed by variable after rename.
return false;
} else {
/*
* We are not in context of local class.
* So this variable is in conflict. Return it
*/
createNameConflictIssue(variable);
return true;
}
} else {
// Any new variable type???
throw new SpoonException("Unexpected variable " + variable.getClass().getName());
}
}
return false;
}
}).first();
}
use of spoon.reflect.declaration.CtType in project spoon by INRIA.
the class Refactoring method copyMethod.
/**
* See doc in {@link CtMethod#copyMethod()}
*/
public static CtMethod<?> copyMethod(final CtMethod<?> method) {
CtMethod<?> clone = method.clone();
String tentativeTypeName = method.getSimpleName() + "Copy";
CtType parent = method.getParent(CtType.class);
while (parent.getMethodsByName(tentativeTypeName).size() > 0) {
tentativeTypeName += "X";
}
final String cloneMethodName = tentativeTypeName;
clone.setSimpleName(cloneMethodName);
parent.addMethod(clone);
new CtScanner() {
@Override
public <T> void visitCtExecutableReference(CtExecutableReference<T> reference) {
CtExecutable<T> declaration = reference.getDeclaration();
if (declaration == null) {
return;
}
if (declaration == method) {
reference.setSimpleName(cloneMethodName);
}
if (reference.getDeclaration() != clone) {
throw new SpoonException("post condition broken " + reference);
}
super.visitCtExecutableReference(reference);
}
}.scan(clone);
return clone;
}
use of spoon.reflect.declaration.CtType in project spoon by INRIA.
the class AccessibleVariablesFinder method getVariable.
private List<CtVariable> getVariable(final CtElement parent) {
final List<CtVariable> variables = new ArrayList<>();
if (parent == null) {
return variables;
}
class VariableScanner extends CtInheritanceScanner {
@Override
public void visitCtStatementList(CtStatementList e) {
for (int i = 0; i < e.getStatements().size(); i++) {
CtStatement ctStatement = e.getStatements().get(i);
if (ctStatement.getPosition() == null) {
}
if (ctStatement.getPosition() != null && ctStatement.getPosition().getSourceStart() > expression.getPosition().getSourceEnd()) {
break;
}
if (ctStatement instanceof CtVariable) {
variables.add((CtVariable) ctStatement);
}
}
super.visitCtStatementList(e);
}
@Override
public <T> void scanCtType(CtType<T> type) {
List<CtField<?>> fields = type.getFields();
for (int i = 0; i < fields.size(); i++) {
CtField<?> ctField = fields.get(i);
if (ctField.hasModifier(ModifierKind.PUBLIC) || ctField.hasModifier(ModifierKind.PROTECTED)) {
variables.add(ctField);
} else if (ctField.hasModifier(ModifierKind.PRIVATE)) {
if (expression.hasParent(type)) {
variables.add(ctField);
}
} else if (expression.getParent(CtPackage.class).equals(type.getParent(CtPackage.class))) {
// default visibility
variables.add(ctField);
}
}
CtTypeReference<?> superclass = type.getSuperclass();
if (superclass != null) {
variables.addAll(getVariable(superclass.getTypeDeclaration()));
}
Set<CtTypeReference<?>> superInterfaces = type.getSuperInterfaces();
for (Iterator<CtTypeReference<?>> iterator = superInterfaces.iterator(); iterator.hasNext(); ) {
CtTypeReference<?> typeReference = iterator.next();
variables.addAll(getVariable(typeReference.getTypeDeclaration()));
}
super.scanCtType(type);
}
@Override
public void visitCtTryWithResource(CtTryWithResource e) {
variables.addAll(e.getResources());
super.visitCtTryWithResource(e);
}
@Override
public void scanCtExecutable(CtExecutable e) {
variables.addAll(e.getParameters());
super.scanCtExecutable(e);
}
@Override
public void visitCtFor(CtFor e) {
for (CtStatement ctStatement : e.getForInit()) {
this.scan(ctStatement);
}
super.visitCtFor(e);
}
@Override
public void visitCtForEach(CtForEach e) {
variables.add(e.getVariable());
super.visitCtForEach(e);
}
@Override
public void visitCtMethod(CtMethod e) {
this.scan(e.getBody());
super.visitCtMethod(e);
}
@Override
public void visitCtLocalVariable(CtLocalVariable e) {
variables.add(e);
super.visitCtLocalVariable(e);
}
@Override
public void visitCtCatch(CtCatch e) {
variables.add(e.getParameter());
super.visitCtCatch(e);
}
}
new VariableScanner().scan(parent);
return variables;
}
Aggregations