NRefactory Найти комментарии XML Doc в коде
Я хотел бы получить документацию XML, связанную с методом, использующим NRefactory. Я промочил ноги, используя следующий код, который я нашел в этом ответе
var parser = new CSharpParser();
SyntaxTree tree = parser.Parse(code, "test.cs");
CSharpUnresolvedFile file = tree.ToTypeSystem();
foreach (IUnresolvedTypeDefinition type in file.TopLevelTypeDefinitions) {
foreach (IUnresolvedMethod method in type.Methods) {
Console.WriteLine(method.Name);
}
}
Однако я взглянул на интерфейс IUnresolvedTypeDefinition, и у него нет свойства "Комментарии". Кроме того, интерфейс IUnresolvedMethod не имеет свойства "Комментарии". Я знаю, что можно получить комментарии, потому что я сделал это с помощью приложения WinForms, связанного со статьей CodeProject, найденной здесь.
Автор демо не использует метод "ToTypeSystem()". Вместо этого он пересекает дерево. Ниже приведены некоторые фрагменты того, что он делает:
SyntaxTree tree = parser.Parse(line, "demo.cs");
foreach (var element in tree.Children)
{
MakeTreeNode(element);
}
static void MakeTreeNode(AstNode node)
{
Console.WriteLine(GetNodeTitle(node));
foreach (AstNode child in node.Children)
{
MakeTreeNode(child);
}
}
static string GetNodeTitle(AstNode node)
{
StringBuilder b = new StringBuilder();
b.Append(node.Role.ToString());
b.Append(": ");
b.Append(node.GetType().Name);
bool hasProperties = false;
foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (p.Name == "NodeType" || p.Name == "IsNull" || p.Name == "IsFrozen" || p.Name == "HasChildren")
continue;
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool))
{
if (!hasProperties)
{
hasProperties = true;
b.Append(" (");
}
else
{
b.Append(", ");
}
b.Append(p.Name);
b.Append(" = ");
try
{
object val = p.GetValue(node, null);
b.Append(val != null ? val.ToString() : "**null**");
}
catch (TargetInvocationException ex)
{
b.Append("**" + ex.InnerException.GetType().Name + "**");
}
}
}
if (hasProperties)
b.Append(")");
return b.ToString() + "\n";
}
Мне было интересно, есть ли метод в NRefactory API, который бы получал документацию, связанную с методом в фрагменте кода C#.
1 ответ
Я нашел метод, который получит мне документацию, связанную с методом в NRefactory API. Это метод "GetDocumentation", который имеет две перегрузки
- DocumentationComment GetDocumentation(сущность IEntity);
- DocumentationComment GetDocumentation(сущность IUnresolvedEntity, IEntity resolvedEntity);
Ниже приведен пример использования
SyntaxTree tree = parser.Parse(line, "demo.cs");
var testClass = tree.Descendants.OfType<TypeDeclaration>().Single(x => x.Members == Method);
var testClassAttributes = testClass.Attributes.SelectMany(x => x.Attributes).ToArray();
List<Dictionary<string, object>> myList = new List<Dictionary<string, object>>();
string nombreControlador = null;
string rutaControlador = null;
string actionKeyPath = null;
string fullControllerPath = null;
int counter = 0;
CSharpUnresolvedFile file = tree.ToTypeSystem();
foreach (IUnresolvedTypeDefinition type in file.TopLevelTypeDefinitions)
{
nombreControlador = type.Name;
actionKeyPath = type.Fields.Skip(1).FirstOrDefault().ConstantValue.ToString();
fullControllerPath = type.Fields.First().ConstantValue.ToString();
rutaControlador = type.FullName;
foreach (IUnresolvedMethod method in type.Methods)
{
string documentation = file.GetDocumentation(method).Trim();
XDocument doc = XDocument.Parse("<documentation>" + documentation + "</documentation>");
Dictionary<string, object> myDic = new Dictionary<string, object>();
Console.WriteLine(method.Name);
myDic.Add("MethodSignature", method.Name);
myDic.Add("MethodDescription", doc.Descendants().Select(e => (string)e.Element("summary")).FirstOrDefault());
myDic.Add("ActionKeyPath", actionKeyPath == null? "" : actionKeyPath);
myDic.Add("Counter", ++counter);
myDic.Add("FullControllerPath", fullControllerPath == null? "" : fullControllerPath);
myDic.Add("Route", method.Attributes == null ? "" : method.Attributes.Count <= 1 || method.Attributes.Skip(1) == null? "" : method.Attributes.SelectMany(a => a.);
myDic.Add("Verb", "");
myDic.Add("Input", "");
myDic.Add("Output", "");
myList.Add(myDic);
}
}
Я использую 5.0 версию NRefactorize, кстати. Я помню, как читал где-то, что версия 5.0 включает комментарии в абстрактном синтаксическом дереве