Skip to content

Instantly share code, notes, and snippets.

@akimboyko
Last active December 17, 2015 06:29
Show Gist options
  • Select an option

  • Save akimboyko/5566054 to your computer and use it in GitHub Desktop.

Select an option

Save akimboyko/5566054 to your computer and use it in GitHub Desktop.
Roslyn CTP: asynchronously search for `return null;` among all sources of solution.
// load workspace, i.e. solution from Visual Studio
using(var workspace = Workspace.LoadSolution(solutionPath))
{
// save a reference to original state
var origianlSolution = workspace.CurrentSolution;
// build syntax root and semantic model asynchronously in parallel
// for all documents from all projects
returnNulls =
origianlSolution
.Projects
.AsParallel()
.AsUnordered()
.WithCancellation(cancellationToken)
.SelectMany(project => project.Documents)
.Select(document => document.GetSyntaxRootAsync(cancellationToken))
// calculate complexity for all methods in parallel
.SelectMany(syntaxRootAsync =>
FindReturnNull(syntaxRootAsync, cancellationToken).Result)
.ToArray();
// throw an exception if more then 1 minute passed since start
cancellationToken.ThrowIfCancellationRequested();
}
// statements for `return null;`
private static readonly Func<StatementSyntax, bool> returnNullStatement =
PredicateBuilder
.True<StatementSyntax>()
.And(s => s is ReturnStatementSyntax)
.And(s => (s as ReturnStatementSyntax).Expression != null)
.And(s => (s as ReturnStatementSyntax).Expression.Kind == SyntaxKind.NullLiteralExpression)
.Compile();
// process descendant nodes of syntaxRoot
private static async Task<IEnumerable<ReturnNull>> FindReturnNull(
Task<CommonSyntaxNode> syntaxRootAsync,
CancellationToken cancellationToken)
{
return
(await syntaxRootAsync)
.DescendantNodes()
.OfType<ReturnStatementSyntax>()
.Where(returnNull => returnNullStatement(returnNull))
.Select(returnNull =>
new ReturnNull
{
TypeIdentifier = GetParentSyntax<TypeDeclarationSyntax>(returnNull).Identifier.ValueText,
SourcesSample = returnNull.ToString(),
FilePath = returnNull.GetLocation().SourceTree.FilePath,
SourceLine = returnNull
.GetLocation().SourceTree
.GetLineSpan(returnNull.Span, true, cancellationToken)
.StartLinePosition.Line + 1
});
}
@akimboyko

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment