Last active
December 17, 2015 06:29
-
-
Save akimboyko/5566054 to your computer and use it in GitHub Desktop.
Roslyn CTP: asynchronously search for `return null;` among all sources of solution.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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 | |
| }); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Full sample is at github