Translate

viernes, 16 de febrero de 2024

Chequeando "TODOs" con Roslyn


Vamos a buscar // TODO: ... con Roslyn 

Para empezar en una aplicación de consola simple agreguemos algunos paquetes. Microsoft.CodeAnalysis.CSharp y Microsoft.CodeAnalysis.CSharp.Workspaces son lo que necesitamos.

Y hacemos esto: 


const int ExitOK = 0;

const int ExitError = 99;

const int ExitIssueFound = 1;


static async Task<int> MainAsync(string[] args)

{

var workspace = await GetWorkspace().ConfigureAwait(false);

if (workspace == null)

return ExitError;

using (workspace)

{

var issueFound = false;

foreach (var project in workspace.CurrentSolution.Projects)

{

foreach (var document in project.Documents)

{

var documentWritten = false;

var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);

foreach (var item in root.DescendantTrivia().Where(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia)))

{

var match = Regex.Match(item.ToFullString(), @"//\s?TODO:\s*(.*)");

if (match.Success)

{

issueFound = true;

var text = match.Groups[1].Value;

if (!documentWritten)

{

documentWritten = true;

Console.WriteLine(MinimizePath(document.FilePath));

}

var position = item.GetLocation().GetMappedLineSpan();

var line = position.StartLinePosition.Line;

Console.WriteLine($"\tL{line}:\t{text}");

}

}

}

}

return issueFound ? ExitIssueFound : ExitOK;

}

}


static async Task<Workspace> GetWorkspace()

{

var workspace = MSBuildWorkspace.Create();

var solution = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault();

if (solution != null)

{

await workspace.OpenSolutionAsync(solution).ConfigureAwait(false);

return workspace;

}

var project = Directory.EnumerateFiles(Environment.CurrentDirectory, "*.csproj", SearchOption.TopDirectoryOnly).FirstOrDefault();

if (project != null)

{

await workspace.OpenProjectAsync(project).ConfigureAwait(false);

return workspace;

}

return null;

}


static string MinimizePath(string path)

{

return path.Remove(0, Environment.CurrentDirectory.Length + 1);

}