package sharpen.core.csharp;
import sharpen.core.csharp.ast.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CSharpRewritingVisitor extends CSVisitor {
public CSharpRewritingVisitor() {
// TODO Auto-generated constructor stub
}
@Override
public void visit(CSArrayCreationExpression node) {
CSharpTypeReferenceVisitor arrayElementTypeVisitor = new CSharpTypeReferenceVisitor(this);
node.elementType().accept(arrayElementTypeVisitor);
if (null != node.length()) {
node.length().accept(this);
}
if (null != node.initializer()) {
node.initializer().accept(this);
}
}
@Override
public void visit(CSArrayInitializerExpression node) {
}
@Override
public void visit(final CSArrayTypeReference node) {
node.elementType().accept(this);
}
@Override
public void visit(CSAttribute node) {
}
@Override
public void visit(CSBaseExpression node) {
}
@Override
public void visit(CSBlock node) {
visitList(node.statements());
}
@Override
public void visit(CSBoolLiteralExpression node) {
}
@Override
public void visit(CSBreakStatement node) {
}
@Override
public void visit(CSCaseClause node) {
visitList(node.expressions());
node.body().accept(this);
}
@Override
public void visit(CSCastExpression node) {
node.type().accept(this);
if (null != node.expression()) {
node.expression().accept(this);
}
}
@Override
public void visit(CSCatchClause node) {
CSVariableDeclaration ex = node.exception();
if (ex != null) {
ex.accept(this);
}
node.body().accept(this);
}
@Override
public void visit(CSCharLiteralExpression node) {
}
@Override
public void visit(CSClass node) {
visitList(node.attributes());
visitList(node.typeParameters());
visitList(node.baseTypes());
visitList(node.constructors());
visitList(node.members());
}
@Override
public void visit(CSCompilationUnit node) {
visitList(node.usings());
visitList(node.types());
}
@Override
public void visit(CSConditionalExpression node) {
node.expression().accept(this);
node.trueExpression().accept(this);
node.falseExpression().accept(this);
}
@Override
public void visit(CSConstructor node) {
node.body().accept(this);
for (final CSVariableDeclaration vdecl : node.parameters())
vdecl.accept(this);
node.body().accept(this);
}
@Override
public void visit(CSConstructorInvocationExpression node) {
}
@Override
public void visit(CSContinueStatement node) {
}
@Override
public void visit(CSDeclarationExpression node) {
node.declaration().accept(this);
}
@Override
public void visit(CSDeclarationStatement node) {
node.declaration().accept(this);
}
@Override
public void visit(CSDelegate node) {
}
@Override
public void visit(CSDestructor node) {
node.body().accept(this);
}
@Override
public void visit(CSDocTagNode node) {
visitList(node.attributes());
visitList(node.fragments());
}
@Override
public void visit(CSDocTextNode node) {
}
@Override
public void visit(CSDocTextOverlay node) {
}
@Override
public void visit(CSDoStatement node) {
node.body().accept(this);
node.expression().accept(this);
}
@Override
public void visit(CSEnum node) {
}
@Override
public void visit(CSEnumValue node) {
}
@Override
public void visit(CSEvent node) {
node.type().accept(this);
final CSBlock addBlock = node.getAddBlock();
if (addBlock != null)
addBlock.accept(this);
final CSBlock removeBlock = node.getRemoveBlock();
if (removeBlock != null)
removeBlock.accept(this);
}
@Override
public void visit(CSExpressionStatement node) {
node.expression().accept(this);
}
@Override
public void visit(CSField node) {
}
@Override
public void visit(CSForEachStatement node) {
node.variable().accept(this);
node.expression().accept(this);
node.body().accept(this);
}
@Override
public void visit(CSForStatement node) {
if (null != node.expression()) {
node.expression().accept(this);
}
node.body().accept(this);
}
@Override
public void visit(CSGotoStatement node) {
if (node.target() != null) {
node.target().accept(this);
}
}
@Override
public void visit(CSIfStatement node) {
node.expression().accept(this);
node.trueBlock().accept(this);
if (!node.falseBlock().isEmpty()) {
node.falseBlock().accept(this);
}
}
@Override
public void visit(CSIndexedExpression node) {
node.expression().accept(this);
}
@Override
public void visit(CSInfixExpression node) {
node.lhs().accept(this);
node.rhs().accept(this);
}
@Override
public void visit(CSInterface node) {
}
@Override
public void visit(CSLabelStatement node) {
}
@Override
public void visit(CSLineComment node) {
}
@Override
public void visit(CSLockStatement node) {
}
static final Pattern META_VARIABLE_PATTERN = Pattern.compile("\\$(\\w+)");
@Override
public void visit(CSMacro node) {
final String template = node.template();
final Matcher matcher = META_VARIABLE_PATTERN.matcher(template);
while (matcher.find()) {
Object value = node.resolveVariable(matcher.group(1));
// value is either a single node or a list of nodes
if (value instanceof CSNode) {
((CSNode)value).accept(this);
}
matcher.end();
}
}
@Override
public void visit(CSMacroExpression node) {
node.macro().accept(this);
}
@Override
public void visit(CSMacroTypeReference node) {
node.macro().accept(this);
}
@Override
public void visit(CSMemberReferenceExpression node) {
node.expression().accept(this);
}
@Override
public void visit(CSMethod node) {
node.returnType().accept(this);
for (final CSVariableDeclaration vdecl : node.parameters())
vdecl.accept(this);
node.body().accept(this);
}
@Override
public void visit(CSMethodInvocationExpression node) {
}
@Override
public void visit(CSNullLiteralExpression node) {
}
@Override
public void visit(CSNumberLiteralExpression node) {
}
@Override
public void visit(CSParenthesizedExpression node) {
node.expression().accept(this);
}
@Override
public void visit(CSPostfixExpression node) {
node.operand().accept(this);
}
@Override
public void visit(CSPrefixExpression node) {
node.operand().accept(this);
}
@Override
public void visit(CSProperty node) {
node.type().accept(this);
final CSBlock getter = node.getter();
if (getter != null)
getter.accept(this);
final CSBlock setter = node.setter();
if (setter != null)
setter.accept(this);
}
@Override
public void visit(CSReferenceExpression node) {
}
@Override
public void visit(CSRemovedExpression node) {
throw new IllegalStateException("Unexpected removal of expression: " + node.toString());
}
@Override
public void visit(CSReturnStatement node) {
if (null != node.expression()) {
node.expression().accept(this);
}
}
@Override
public void visit(CSStringLiteralExpression node) {
}
@Override
public void visit(CSStruct node) {
}
@Override
public void visit(CSSwitchStatement node) {
node.expression().accept(this);
}
@Override
public void visit(CSThisExpression node) {
}
@Override
public void visit(CSThrowStatement node) {
if (null != node.expression()) {
node.expression().accept(this);
}
}
@Override
public void visit(CSTryStatement node) {
node.body().accept(this);
visitList(node.catchClauses());
if (null != node.finallyBlock()) {
node.finallyBlock().accept(this);
}
}
@Override
public void visit(CSTypeofExpression node) {
node.type().accept(this);
}
@Override
public void visit(CSTypeParameter node) {
}
@Override
public void visit(CSTypeReference node) {
}
@Override
public void visit(CSNestedTypeReference node) {
node.getParent().accept(this);
node.getChild().accept(this);
}
@Override
public void visit(CSUncheckedExpression node) {
node.expression().accept(this);
}
@Override
public void visit(CSUsing node) {
}
@Override
public void visit(CSVariableDeclaration node) {
node.type().accept(this);
if (null != node.initializer()) {
node.initializer().accept(this);
}
}
@Override
public void visit(CSWhileStatement node) {
}
class CSharpTypeReferenceVisitor extends CSVisitor {
private CSVisitor _delegate;
private StringBuffer _sb = new StringBuffer();
CSharpTypeReferenceVisitor(CSVisitor delegate) {
_delegate = delegate;
}
@Override
public void visit(CSArrayTypeReference node) {
node.elementType().accept(_delegate);
for (int i=0; i < node.dimensions(); ++i) {
_sb.append("[]");
}
}
public void visit(CSTypeReferenceExpression node) {
node.accept(_delegate);
}
@Override
public void visit(CSTypeReference node) {
node.accept(_delegate);
}
String sufix() {
return _sb.toString();
}
}
@Override
public void visit(CSUserDefinedConversion conv) {
conv.sourceType().accept(this);
conv.targetType().accept(this);
conv.body().accept(this);
}
}