Ejemplo n.º 1
0
        private static bool IsRedundantAssignment(ISymbol left, AssignmentExpressionSyntax assignment, SyntaxNodeAnalysisContext context)
        {
            if (left is IDiscardSymbol ||
                assignment.TryFirstAncestor <ObjectCreationExpressionSyntax>(out _))
            {
                return(false);
            }

            if (assignment.TryFirstAncestor <MemberDeclarationSyntax>(out var member))
            {
                if (!(member is ConstructorDeclarationSyntax) &&
                    context.SemanticModel.TryGetType(assignment.Left, context.CancellationToken, out var type) &&
                    FieldOrProperty.TryCreate(left, out _))
                {
                    if (type == KnownSymbol.Boolean ||
                        type.TypeKind == TypeKind.Enum)
                    {
                        return(false);
                    }
                }

                using (var walker = AssignmentExecutionWalker.For(left, member, Scope.Member, context.SemanticModel, context.CancellationToken))
                {
                    foreach (var candidate in walker.Assignments)
                    {
                        if (candidate == assignment)
                        {
                            continue;
                        }

                        if (!MemberPath.Equals(candidate.Left, assignment.Left))
                        {
                            continue;
                        }

                        if (candidate.IsExecutedBefore(assignment) == ExecutedBefore.Yes)
                        {
                            if (left is IParameterSymbol parameter &&
                                parameter.RefKind == RefKind.Out &&
                                assignment.TryFirstAncestor <BlockSyntax>(out var assignmentBlock) &&
                                candidate.TryFirstAncestor <BlockSyntax>(out var candidateBlock) &&
                                (candidateBlock.Contains(assignmentBlock) ||
                                 candidateBlock.Statements.Last() is ReturnStatementSyntax))
                            {
                                return(false);
                            }

                            using (var nameWalker = IdentifierNameWalker.Borrow(assignment.Right))
                            {
                                foreach (var name in nameWalker.IdentifierNames)
                                {
                                    if (left.Name == name.Identifier.ValueText &&
                                        context.SemanticModel.TryGetSymbol(
                                            name,
                                            context.CancellationToken,
                                            out ISymbol symbol) &&
                                        symbol.Equals(left))
                                    {
                                        return(false);
                                    }
                                }
                            }

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }