public static void Free(RemoveRedundantAssignmentWalker walker)
            {
                walker.Symbol            = null;
                walker.SemanticModel     = null;
                walker.CancellationToken = default;

                _cachedInstance = walker;
            }
            public static bool GetResultAndFree(RemoveRedundantAssignmentWalker walker)
            {
                bool result = walker.Result;

                walker.Result            = false;
                walker.Symbol            = default;
                walker.SemanticModel     = default;
                walker.CancellationToken = default;
                _cachedInstance          = walker;

                return(result);
            }
            public static RemoveRedundantAssignmentWalker GetInstance()
            {
                RemoveRedundantAssignmentWalker walker = _cachedInstance;

                if (walker != null)
                {
                    _cachedInstance = null;
                }
                else
                {
                    walker = new RemoveRedundantAssignmentWalker();
                }

                return(walker);
            }
            public static RemoveRedundantAssignmentWalker GetInstance()
            {
                RemoveRedundantAssignmentWalker walker = _cachedInstance;

                if (walker != null)
                {
                    Debug.Assert(walker.Symbol == null);
                    Debug.Assert(walker.SemanticModel == null);
                    Debug.Assert(walker.CancellationToken == default);

                    _cachedInstance = null;
                    return(walker);
                }

                return(new RemoveRedundantAssignmentWalker());
            }
        private static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (assignmentInfo.Left is not IdentifierNameSyntax identifierName)
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(assignmentInfo.Statement);

            if (!statementsInfo.Success)
            {
                return;
            }

            int index = statementsInfo.IndexOf(assignmentInfo.Statement);

            if (index == statementsInfo.Count - 1)
            {
                return;
            }

            if (index > 0)
            {
                StatementSyntax previousStatement = statementsInfo[index - 1];

                SimpleAssignmentStatementInfo assignmentInfo2 = SyntaxInfo.SimpleAssignmentStatementInfo(previousStatement);

                if (assignmentInfo2.Success &&
                    assignmentInfo2.Left is IdentifierNameSyntax identifierName2 &&
                    string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    return;
                }
            }

            StatementSyntax nextStatement = statementsInfo[index + 1];

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (nextStatement is not ReturnStatementSyntax returnStatement)
            {
                return;
            }

            if (returnStatement.Expression?.WalkDownParentheses() is not IdentifierNameSyntax identifierName3)
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName3.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            switch (symbol?.Kind)
            {
            case SymbolKind.Local:
            {
                break;
            }

            case SymbolKind.Parameter:
            {
                if (((IParameterSymbol)symbol).RefKind != RefKind.None)
                {
                    return;
                }

                break;
            }

            default:
            {
                return;
            }
            }

            if (IsAssignedInsideAnonymousFunctionButDeclaredOutsideOfIt())
            {
                return;
            }

            bool result;
            RemoveRedundantAssignmentWalker walker = null;

            try
            {
                walker = RemoveRedundantAssignmentWalker.GetInstance();

                walker.Symbol            = symbol;
                walker.SemanticModel     = context.SemanticModel;
                walker.CancellationToken = context.CancellationToken;
                walker.Result            = false;

                walker.Visit(assignmentInfo.Right);

                result = walker.Result;
            }
            finally
            {
                if (walker != null)
                {
                    RemoveRedundantAssignmentWalker.Free(walker);
                }
            }

            if (result)
            {
                return;
            }

            if (IsDeclaredInTryStatementOrCatchClauseAndReferencedInFinallyClause(context, assignmentInfo.Statement, symbol))
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.RemoveRedundantAssignment, assignment);

            bool IsAssignedInsideAnonymousFunctionButDeclaredOutsideOfIt()
            {
                SyntaxNode declaringSyntax = null;
                SyntaxNode n = assignment.Parent;

                do
                {
                    if (CSharpFacts.IsAnonymousFunctionExpression(n.Kind()))
                    {
                        if (declaringSyntax == null)
                        {
                            declaringSyntax = symbol.GetSyntaxOrDefault();

                            Debug.Assert(declaringSyntax != null, "");

                            if (declaringSyntax == null)
                            {
                                break;
                            }

                            SyntaxDebug.Assert(declaringSyntax.IsKind(SyntaxKind.VariableDeclarator, SyntaxKind.Parameter), declaringSyntax);
                        }

                        SyntaxNode n2 = declaringSyntax.Parent;

                        do
                        {
                            if (CSharpFacts.IsAnonymousFunctionExpression(n2.Kind()))
                            {
                                return(!object.ReferenceEquals(n, n2));
                            }

                            if (n2 is MemberDeclarationSyntax)
                            {
                                break;
                            }

                            n2 = n2.Parent;
                        }while (n2 != null);

                        return(true);
                    }
                    else if (n is MemberDeclarationSyntax)
                    {
                        break;
                    }

                    n = n.Parent;
                }while (n != null);

                return(false);
            }
        }
Exemple #6
0
        internal static void AnalyzeSimpleAssignment(SyntaxNodeAnalysisContext context)
        {
            if (context.Node.ContainsDiagnostics)
            {
                return;
            }

            if (context.Node.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            var assignment = (AssignmentExpressionSyntax)context.Node;

            SimpleAssignmentStatementInfo assignmentInfo = SyntaxInfo.SimpleAssignmentStatementInfo(assignment);

            if (!assignmentInfo.Success)
            {
                return;
            }

            if (!(assignmentInfo.Left is IdentifierNameSyntax identifierName))
            {
                return;
            }

            StatementListInfo statementsInfo = SyntaxInfo.StatementListInfo(assignmentInfo.Statement);

            if (!statementsInfo.Success)
            {
                return;
            }

            int index = statementsInfo.IndexOf(assignmentInfo.Statement);

            if (index == statementsInfo.Count - 1)
            {
                return;
            }

            if (index > 0)
            {
                StatementSyntax previousStatement = statementsInfo[index - 1];

                SimpleAssignmentStatementInfo assignmentInfo2 = SyntaxInfo.SimpleAssignmentStatementInfo(previousStatement);

                if (assignmentInfo2.Success &&
                    assignmentInfo2.Left is IdentifierNameSyntax identifierName2 &&
                    string.Equals(identifierName.Identifier.ValueText, identifierName2.Identifier.ValueText, StringComparison.Ordinal))
                {
                    return;
                }
            }

            StatementSyntax nextStatement = statementsInfo[index + 1];

            if (nextStatement.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            if (!(nextStatement is ReturnStatementSyntax returnStatement))
            {
                return;
            }

            if (!(returnStatement.Expression?.WalkDownParentheses() is IdentifierNameSyntax identifierName3))
            {
                return;
            }

            if (!string.Equals(identifierName.Identifier.ValueText, identifierName3.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            ISymbol symbol = context.SemanticModel.GetSymbol(identifierName, context.CancellationToken);

            switch (symbol?.Kind)
            {
            case SymbolKind.Local:
            {
                break;
            }

            case SymbolKind.Parameter:
            {
                if (((IParameterSymbol)symbol).RefKind != RefKind.None)
                {
                    return;
                }

                break;
            }

            default:
            {
                return;
            }
            }

            RemoveRedundantAssignmentWalker walker = RemoveRedundantAssignmentWalker.GetInstance();

            walker.Symbol            = symbol;
            walker.SemanticModel     = context.SemanticModel;
            walker.CancellationToken = context.CancellationToken;
            walker.Result            = false;

            walker.Visit(assignmentInfo.Right);

            bool result = walker.Result;

            RemoveRedundantAssignmentWalker.Free(walker);

            if (result)
            {
                return;
            }

            DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.RemoveRedundantAssignment, assignment);
        }