/*
Copyright (C) 2013 Raquel Pau and Albert Coroleu.
Walkmod is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Walkmod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Walkmod. If not, see <http://www.gnu.org/licenses/>.*/
package org.walkmod.javalang.ast;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.walkmod.javalang.ast.expr.FieldAccessExpr;
import org.walkmod.javalang.ast.expr.NameExpr;
import org.walkmod.javalang.ast.expr.ThisExpr;
import org.walkmod.javalang.visitors.VoidVisitorAdapter;
public class Refactorization {
/**
* Generic method to rename a SymbolDefinition variable/parameter.
* @param n variable to rename.
* @param newName new name to set.
* @return if the rename procedure has been applied successfully.
*/
public boolean refactorVariable(SymbolDefinition n, final String newName) {
Map<String, SymbolDefinition> scope = n.getVariableDefinitions();
if (!scope.containsKey(newName)) {
if (n.getUsages() != null) {
List<SymbolReference> usages = new LinkedList<SymbolReference>(n.getUsages());
VoidVisitorAdapter<?> visitor = new VoidVisitorAdapter<Object>() {
@Override
public void visit(NameExpr nexpr, Object ctx) {
Map<String, SymbolDefinition> innerScope = nexpr.getVariableDefinitions();
if (innerScope.containsKey(newName)) {
nexpr.getParentNode().replaceChildNode(nexpr, new FieldAccessExpr(new ThisExpr(), newName));
} else {
nexpr.getParentNode().replaceChildNode(nexpr, new NameExpr(newName));
}
}
@Override
public void visit(FieldAccessExpr nexpr, Object ctx) {
nexpr.getParentNode().replaceChildNode(nexpr,
new FieldAccessExpr(nexpr.getScope(), nexpr.getTypeArgs(), newName));
}
};
for (SymbolReference usage : usages) {
Node aux = (Node) usage;
aux.accept(visitor, null);
}
}
return true;
}
return false;
}
}