use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.
the class DefaultJavaPrettyPrinter method visitCtCase.
@Override
@SuppressWarnings("rawtypes")
public <E> void visitCtCase(CtCase<E> caseStatement) {
enterCtStatement(caseStatement);
if (caseStatement.getCaseExpression() != null) {
printer.writeKeyword("case").writeSpace();
// writing enum case expression
if (caseStatement.getCaseExpression() instanceof CtFieldAccess) {
final CtFieldReference variable = ((CtFieldAccess) caseStatement.getCaseExpression()).getVariable();
// In noclasspath mode, we don't have always the type of the declaring type.
if (variable.getType() != null && variable.getDeclaringType() != null && variable.getType().getQualifiedName().equals(variable.getDeclaringType().getQualifiedName())) {
printer.writeIdentifier(variable.getSimpleName());
} else {
scan(caseStatement.getCaseExpression());
}
} else {
scan(caseStatement.getCaseExpression());
}
} else {
printer.writeKeyword("default");
}
printer.writeSpace().writeSeparator(":").incTab();
for (CtStatement statement : caseStatement.getStatements()) {
printer.writeln();
elementPrinterHelper.writeStatement(statement);
}
printer.decTab();
}
use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.
the class ElementPrinterHelper method writeImports.
/**
* writes the imports in a specific order (eg all static imports together
*/
public void writeImports(Collection<CtImport> imports) {
Set<String> setImports = new HashSet<>();
Set<String> setStaticImports = new HashSet<>();
for (CtImport ctImport : imports) {
String importTypeStr;
switch(ctImport.getImportKind()) {
case TYPE:
CtTypeReference typeRef = (CtTypeReference) ctImport.getReference();
importTypeStr = typeRef.getQualifiedName();
if (!isJavaLangClasses(importTypeStr)) {
setImports.add(importTypeStr);
}
break;
case ALL_TYPES:
CtPackageReference packageRef = (CtPackageReference) ctImport.getReference();
importTypeStr = packageRef.getQualifiedName() + ".*";
if (!isJavaLangClasses(importTypeStr)) {
setImports.add(importTypeStr);
}
break;
case METHOD:
CtExecutableReference execRef = (CtExecutableReference) ctImport.getReference();
if (execRef.getDeclaringType() != null) {
setStaticImports.add(this.removeInnerTypeSeparator(execRef.getDeclaringType().getQualifiedName()) + "." + execRef.getSimpleName());
}
break;
case FIELD:
CtFieldReference fieldRef = (CtFieldReference) ctImport.getReference();
setStaticImports.add(this.removeInnerTypeSeparator(fieldRef.getDeclaringType().getQualifiedName()) + "." + fieldRef.getSimpleName());
break;
case ALL_STATIC_MEMBERS:
CtTypeReference typeStarRef = (CtTypeReference) ctImport.getReference();
importTypeStr = typeStarRef.getQualifiedName();
if (!isJavaLangClasses(importTypeStr)) {
setStaticImports.add(importTypeStr);
}
break;
}
}
List<String> sortedImports = new ArrayList<>(setImports);
Collections.sort(sortedImports);
boolean isFirst = true;
for (String importLine : sortedImports) {
if (isFirst) {
printer.writeln();
printer.writeln();
isFirst = false;
}
printer.writeKeyword("import").writeSpace();
writeQualifiedName(importLine).writeSeparator(";").writeln();
}
if (setStaticImports.size() > 0) {
if (isFirst) {
printer.writeln();
}
printer.writeln();
List<String> sortedStaticImports = new ArrayList<>(setStaticImports);
Collections.sort(sortedStaticImports);
for (String importLine : sortedStaticImports) {
printer.writeKeyword("import").writeSpace().writeKeyword("static").writeSpace();
writeQualifiedName(importLine).writeSeparator(";").writeln();
}
}
}
use of spoon.reflect.reference.CtFieldReference in project spoon by INRIA.
the class ElementPrinterHelper method writeAnnotationElement.
/**
* Writes an annotation element.
*/
public void writeAnnotationElement(Factory factory, Object value) {
if (value instanceof CtTypeAccess) {
prettyPrinter.scan((CtTypeAccess) value);
printer.writeSeparator(".").writeKeyword("class");
} else if (value instanceof CtFieldReference) {
prettyPrinter.scan(((CtFieldReference<?>) value).getDeclaringType());
printer.writeSeparator(".").writeIdentifier(((CtFieldReference<?>) value).getSimpleName());
} else if (value instanceof CtElement) {
prettyPrinter.scan((CtElement) value);
} else if (value instanceof String) {
printer.writeLiteral("\"" + LiteralHelper.getStringLiteral((String) value, true) + "\"");
} else if (value instanceof Collection) {
try (ListPrinter lp = createListPrinter(false, "{", false, true, ",", false, false, "}")) {
for (Object obj : (Collection<?>) value) {
lp.printSeparatorIfAppropriate();
writeAnnotationElement(factory, obj);
}
}
} else if (value instanceof Object[]) {
try (ListPrinter lp = createListPrinter(false, "{", false, true, ",", false, false, "}")) {
for (Object obj : (Object[]) value) {
lp.printSeparatorIfAppropriate();
writeAnnotationElement(factory, obj);
}
}
} else if (value instanceof Enum) {
try (Writable c = prettyPrinter.getContext().modify().ignoreGenerics(true)) {
prettyPrinter.scan(factory.Type().createReference(((Enum<?>) value).getDeclaringClass()));
}
printer.writeSeparator(".");
printer.writeIdentifier(value.toString());
} else {
// it probably prints, boolean, number, ...
printer.writeLiteral(value.toString());
}
}
use of spoon.reflect.reference.CtFieldReference 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.reference.CtFieldReference in project spoon by INRIA.
the class FieldAccessTest method testFieldAccessAutoExplicit.
@Test
public void testFieldAccessAutoExplicit() throws Exception {
CtClass mouse = (CtClass) ModelUtils.buildClass(Mouse.class);
CtMethod method = mouse.filterChildren((CtMethod m) -> "meth1".equals(m.getSimpleName())).first();
CtFieldReference ageFR = method.filterChildren((CtFieldReference fr) -> "age".equals(fr.getSimpleName())).first();
// first is the field printed with implicit "this."
assertEquals("age", ageFR.getParent().toString());
// add local variable declaration which hides the field declaration
method.getBody().insertBegin((CtStatement) mouse.getFactory().createCodeSnippetStatement("int age = 1").compile());
// now the field access must use explicit "this."
assertEquals("this.age", ageFR.getParent().toString());
}
Aggregations