visual studio generar fuente etiquetas documentar documentacion como codigo clases c# nested nodes roslyn

studio - Cómo medir el nivel de anidación del método usando C#Roslyn



generar documentacion visual studio 2017 (2)

Quiero medir un "nivel de anidación" de un método utilizando Roslyn, por ejemplo: si el método contiene solo una expresión, su nivel es 0. Si el método contiene anidado if(cond1) if(cond2) su nivel es 1.

Intento usar los nodos de Roslyn, pero no entiendo cómo obtener solo el cuerpo del momento o la construcción si no es así y otras cosas.


Puede usar SyntaxVisitor para esto: recorre recursivamente el árbol de sintaxis y ejecuta su código para cada nodo, dependiendo de su tipo.

Tendrá que especificar cómo exactamente deben comportarse varios tipos de declaraciones. Por ejemplo:

  • Para declaraciones simples (como ExpressionStatementSyntax ) simplemente devuelve 0.
  • Para declaraciones de anidamiento (incluidas IfStatementSyntax y muchas otras), devuelva la profundidad de su declaración secundaria + 1. Obtiene la profundidad del hijo llamando recursivamente a Visit() en él.
  • Para BlockSyntax , devuelve la profundidad máxima de sus hijos.

En el código, se vería algo así como:

class NestingLevelVisitor : SyntaxVisitor<int> { public override int DefaultVisit(SyntaxNode node) { throw new NotSupportedException(); } public override int VisitMethodDeclaration(MethodDeclarationSyntax node) { return Visit(node.Body); } public override int VisitBlock(BlockSyntax node) { return node.Statements.Select(Visit).Max(); } public override int VisitExpressionStatement(ExpressionStatementSyntax node) { return 0; } public override int VisitIfStatement(IfStatementSyntax node) { int result = Visit(node.Statement); if (node.Else != null) { int elseResult = Visit(node.Else.Statement); result = Math.Max(result, elseResult); } return result + 1; } }

Este código está incompleto, deberá agregar modificaciones para todos los otros tipos de declaraciones.

El uso es algo así como:

MethodDeclarationSyntax method = …; int methodNestingLevel = new NestingLevelVisitor().Visit(method);


Esta solución es agradable, pero tenga cuidado con VisitExpressionStatement, ya que puede incluir una expresión lambda, y si desea encontrarla, puede perder una respuesta correcta.