private static ISymbol?GetSymbolIfWhoseTypeIs( SemanticModel model, SyntaxToken token, string instanceType) { var span = token.Span; var symbol = model.LookupSymbols(span.Start, null, token.Text) .FirstOrDefault(); if (symbol is null) { return(null); } var typeSymbol = GetType(symbol); if (typeSymbol is null) { return(null); } var typeFullName = TypeSymbols.GetFullName(typeSymbol); return((instanceType != typeFullName) ? null : symbol); }
private static async Task <Solution> RemoveUsing( Document document, UsingStatementSyntax node, CancellationToken cancellationToken) { var solution = document.Project.Solution; var root = await document.GetSyntaxRootAsync(cancellationToken) .ConfigureAwait(false); if (root is null) { return(solution); } var model = await document.GetSemanticModelAsync(cancellationToken) .ConfigureAwait(false); if (model is null) { return(solution); } var declaration = node.Declaration; if (declaration is null) { return(solution); } var type = declaration.Type; var variables = declaration.Variables; var n = variables.Count; var k = 0; List <VariableDeclaratorSyntax> GetList(Func <string, bool> matches) { var syntaxList = new List <VariableDeclaratorSyntax>(n); for (; k < n; ++k) { var v = variables[k]; var initializer = v.Initializer; if (initializer is null) { continue; } var value = initializer.Value; var o = model.GetOperation(value, cancellationToken); if (o is null) { continue; } var valueType = o.Type; var name = TypeSymbols.GetFullName(valueType); if (matches(name)) { break; } syntaxList.Add(v); } return(syntaxList); } var list = new List <( List <VariableDeclaratorSyntax> InList, List <VariableDeclaratorSyntax> OutList)>(); do { var inList = GetList(s => !Analyzer.DisposesNothing(s)); var outList = GetList(s => Analyzer.DisposesNothing(s)); list.Add((inList, outList)); }while (k < n); VariableDeclarationSyntax ToDeclaration( IEnumerable <VariableDeclaratorSyntax> declarators) { return(SyntaxFactory.VariableDeclaration( type, SyntaxFactory.SeparatedList(declarators))); } var newNode = node.Statement; if (list[0].InList.Count > 0) { for (var count = list.Count - 1; count >= 0; --count) { var(inList, outList) = list[count]; var inStatement = SyntaxFactory.LocalDeclarationStatement( ToDeclaration(inList)); var outStatement = (outList.Count > 0) ? SyntaxFactory.UsingStatement( ToDeclaration(outList), null, newNode) : newNode; newNode = SyntaxFactory.Block(inStatement, outStatement) .WithAdditionalAnnotations(Formatter.Annotation); } } else { for (var count = list.Count - 1; count >= 0; --count) { var(inList, outList) = list[count]; var outStatement = (outList.Count > 0) ? SyntaxFactory.UsingStatement( ToDeclaration(outList), null, newNode) : newNode; newNode = ((inList.Count > 0) ? SyntaxFactory.Block( SyntaxFactory.LocalDeclarationStatement( ToDeclaration(inList)), outStatement) : outStatement) .WithAdditionalAnnotations(Formatter.Annotation); } } var targetNode = (newNode is BlockSyntax && node.Parent is BlockSyntax parent && parent.ChildNodes().Count() == 1) ? parent as SyntaxNode : node; var workspace = solution.Workspace; var formattedNode = Formatter.Format( newNode, Formatter.Annotation, workspace, workspace.Options) .WithTriviaFrom(targetNode); var newRoot = root.ReplaceNode(targetNode, formattedNode); return(solution.WithDocumentSyntaxRoot(document.Id, newRoot)); }
private static void AnalyzeModel( SemanticModelAnalysisContext context) { var cancellationToken = context.CancellationToken; var model = context.SemanticModel; var root = model.SyntaxTree .GetCompilationUnitRoot(cancellationToken); var all = root.DescendantNodes() .OfType <UsingStatementSyntax>(); if (!all.Any()) { return; } IEnumerable <ISymbol> ToSymbols( VariableDeclaratorSyntax v, Func <string, bool> matches) { if (!(model.GetOperation(v, cancellationToken) is IVariableDeclaratorOperation declaratorOperation)) { return(EmptySymbol); } var initialzer = v.Initializer; if (initialzer is null) { return(EmptySymbol); } var value = initialzer.Value; var operation = model.GetOperation(value, cancellationToken); if (operation is null || !matches(TypeSymbols.GetFullName(operation.Type))) { return(EmptySymbol); } return(Create(declaratorOperation.Symbol)); } foreach (var @using in all) { var declaration = @using.Declaration; if (declaration is null) { continue; } var first = declaration.Variables .SelectMany(v => ToSymbols(v, DisposesNothing)) .FirstOrDefault(); if (first is null) { continue; } var location = @using.GetLocation(); var diagnostic = Diagnostic.Create( Rule, location, first.Name); context.ReportDiagnostic(diagnostic); } }