cdc.applic.renaming.core.RenamerImpl Maven / Gradle / Ivy
package cdc.applic.renaming.core;
import java.util.List;
import cdc.applic.expressions.Expression;
import cdc.applic.expressions.ast.AbstractLeafNode;
import cdc.applic.expressions.ast.Node;
import cdc.applic.expressions.ast.RenamableNode;
import cdc.applic.expressions.ast.visitors.AbstractConverter;
import cdc.applic.expressions.literals.Name;
import cdc.applic.expressions.literals.SName;
import cdc.applic.expressions.parsing.Analyzer;
import cdc.applic.expressions.parsing.ParsingEvent;
import cdc.applic.expressions.parsing.TokenType;
import cdc.applic.renaming.Renamer;
import cdc.applic.renaming.RenamingProfile;
/**
* Implementation of {@link Renamer}.
*
* @author Damien Carbonne
*/
public class RenamerImpl implements Renamer {
private final RenamingProfile profile;
private final RenamingVisitor visitor;
public RenamerImpl(RenamingProfile profile) {
this.profile = profile;
this.visitor = new RenamingVisitor();
}
@Override
public RenamingProfile getProfile() {
return profile;
}
@Override
public Node rename(Node node) {
return node.accept(visitor);
}
@Override
public Expression rename(Expression expression) {
final StringBuilder builder = new StringBuilder();
final List events = Analyzer.analyze(expression.getContent());
int index = 0;
while (index < events.size()) {
final ParsingEvent event = events.get(index);
if (index > 0) {
final ParsingEvent previous = events.get(index - 1);
builder.append(expression.getContent()
.substring(previous.getToken().getEndIndex(), event.getToken().getBeginIndex()));
} else {
builder.append(expression.getContent().substring(0, event.getToken().getBeginIndex()));
}
switch (event.getInfo()) {
case PROPERTY_PREFIX:
case REF_PREFIX:
final SName prefix = SName.of(event.getToken().getUnescapedText());
index += 2;
final ParsingEvent event2 = events.get(index);
final SName local = SName.of(event2.getToken().getUnescapedText());
final Name oldName = Name.of(prefix, local);
final Name newPrefixedName = profile.rename(oldName);
builder.append(newPrefixedName.getProtectedLiteral());
break;
case PROPERTY_LOCAL_NAME:
case REF_LOCAL_NAME:
final Name oldLocalName = Name.of(event.getToken().getUnescapedText());
final Name newLocalName = profile.rename(oldLocalName);
builder.append(newLocalName.getProtectedLiteral());
break;
default:
if (event.getToken().getType() == TokenType.EPSILON) {
builder.append(expression.getContent()
.substring(event.getToken().getBeginIndex(), expression.getContent().length()));
} else {
builder.append(event.getToken().getText());
}
break;
}
index++;
}
return new Expression(builder.toString());
}
private class RenamingVisitor extends AbstractConverter {
@Override
public Node visitLeaf(AbstractLeafNode node) {
if (node instanceof RenamableNode) {
final RenamableNode n = (RenamableNode) node;
final Name oldName = n.getName();
final Name newName = profile.rename(oldName);
if (newName.equals(oldName)) {
return node;
} else {
return n.setName(newName);
}
} else {
return node;
}
}
}
}