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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
            }
        }