//
//
//
//
// $Revision$
//
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Ast;
namespace ICSharpCode.NRefactory.Visitors
{
///
/// Prefixes the names of the specified fields with the prefix and replaces the use.
///
public class PrefixFieldsVisitor : AbstractAstVisitor
{
List fields;
List curBlock = new List();
Stack> blocks = new Stack>();
string prefix;
public PrefixFieldsVisitor(List fields, string prefix)
{
this.fields = fields;
this.prefix = prefix;
}
public void Run(INode typeDeclaration)
{
typeDeclaration.AcceptVisitor(this, null);
foreach (VariableDeclaration decl in fields) {
decl.Name = prefix + decl.Name;
}
}
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{
Push();
object result = base.VisitTypeDeclaration(typeDeclaration, data);
Pop();
return result;
}
public override object VisitBlockStatement(BlockStatement blockStatement, object data)
{
Push();
object result = base.VisitBlockStatement(blockStatement, data);
Pop();
return result;
}
public override object VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
Push();
object result = base.VisitMethodDeclaration(methodDeclaration, data);
Pop();
return result;
}
public override object VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration, object data)
{
Push();
object result = base.VisitPropertyDeclaration(propertyDeclaration, data);
Pop();
return result;
}
public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
{
Push();
object result = base.VisitConstructorDeclaration(constructorDeclaration, data);
Pop();
return result;
}
private void Push()
{
blocks.Push(curBlock);
curBlock = new List();
}
private void Pop()
{
curBlock = blocks.Pop();
}
public override object VisitVariableDeclaration(VariableDeclaration variableDeclaration, object data)
{
// process local variables only
if (fields.Contains(variableDeclaration)) {
return null;
}
curBlock.Add(variableDeclaration.Name);
return base.VisitVariableDeclaration(variableDeclaration, data);
}
public override object VisitParameterDeclarationExpression(ParameterDeclarationExpression parameterDeclarationExpression, object data)
{
curBlock.Add(parameterDeclarationExpression.ParameterName);
//print("add parameter ${parameterDeclarationExpression.ParameterName} to block")
return base.VisitParameterDeclarationExpression(parameterDeclarationExpression, data);
}
public override object VisitForeachStatement(ForeachStatement foreachStatement, object data)
{
curBlock.Add(foreachStatement.VariableName);
return base.VisitForeachStatement(foreachStatement, data);
}
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{
string name = identifierExpression.Identifier;
foreach (VariableDeclaration var in fields) {
if (var.Name == name && !IsLocal(name)) {
identifierExpression.Identifier = prefix + name;
break;
}
}
return base.VisitIdentifierExpression(identifierExpression, data);
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression fieldReferenceExpression, object data)
{
if (fieldReferenceExpression.TargetObject is ThisReferenceExpression) {
string name = fieldReferenceExpression.MemberName;
foreach (VariableDeclaration var in fields) {
if (var.Name == name) {
fieldReferenceExpression.MemberName = prefix + name;
break;
}
}
}
return base.VisitMemberReferenceExpression(fieldReferenceExpression, data);
}
bool IsLocal(string name)
{
foreach (List block in blocks) {
if (block.Contains(name))
return true;
}
return curBlock.Contains(name);
}
}
}