Как использовать NRefactory для модификации кода C#
Я пытаюсь использовать NRefactory, чтобы изменить существующий кусок кода C#. Я попытался использовать метод, описанный в этой статье. Я получаю исключение с жалобой на повторяющиеся изменения. Может кто-то указать, что я делаю неправильно, и, возможно, указать мне в правильном направлении?
У меня есть следующий раздел кода:
// contains the source code that needs to be modified
var text = "...";
// is the name of the file in which the target class exists
var fileName = "Foo";
// is the name of the target class
var className = "Foo.cs";
// FormattingOptions and TextEditorOptions are properties available to
// the class containing this code...
var parser = new CSharpParser();
var syntaxTree = parser.Parse(text, fileName);
syntaxTree.Freeze();
var document = new StringBuilderDocument();
document.Text = syntaxTree.ToString(FormattingOptions);
using (var documentScript = new DocumentScript(document, FormattingOptions, TextEditorOptions))
{
var typeDeclarations = syntaxTree.Descendants.OfType<TypeDeclaration>().Where(typeDeclaration => typeDeclaration.Name == className);
var templateProviderDeclaration = typeDeclarations.SingleOrDefault();
if (templateProviderDeclaration != null)
{
var constructorDeclarations = templateProviderDeclaration.Descendants.OfType<ConstructorDeclaration>();
foreach (var constructorDeclaration in constructorDeclarations)
{
var assignmentExpressions = constructorDeclaration.Descendants.OfType<AssignmentExpression>();
foreach (var assignmentExpression in assignmentExpressions)
{
var leftExpression = assignmentExpression.Left;
if (leftExpression != null && leftExpression.ToString(FormattingOptions) == "this.templates")
{
var rightExpression = assignmentExpression.Right;
foreach (var arrayInitializerExpression in rightExpression.Children.OfType<ArrayInitializerExpression>())
{
// uses AddTemplate(), which is an extension method
// which takes in an expression and modifies it, and
// returns an expression
var newExpression = ((ArrayInitializerExpression)arrayInitializerExpression).AddTemplate();
documentScript.Replace(arrayInitializerExpression, newExpression);
}
}
}
}
}
// text retrieved here is *clobbered*, by a few characters
text = documentScript.CurrentDocument.Text;
}
Другой код...
public static class ExtensionMethods
{
public static ArrayInitializerExpression AddTemplate(this ArrayInitializerExpression expression)
{
// TODO : will modify the AST for the target expression
return (ArrayInitializerExpression)expression.Clone();
}
}
Обновить:
Я пытаюсь изменить строку следующим образом:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() }
};
чтобы:
this.templates = new Dictionary<string, ITemplate>
{
{ "Foo", new FooTemplate() },
{ "Bar", new BarTemplate() }
};
Для целей этого вопроса точные особенности изменений, которые я пытаюсь внести, не важны. Я подозреваю, что у меня что-то не совсем правильно построено, но я не могу понять, в этом ли проблема.