Ejemplo n.º 1
0
        private static bool IsAddedToFieldOrProperty(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooledInvocations = InvocationWalker.Create(block))
            {
                foreach (var invocation in pooledInvocations.Item.Invocations)
                {
                    var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol;
                    if (method?.Name == "Add")
                    {
                        using (var pooledIdentifiers = IdentifierNameWalker.Create(invocation.ArgumentList))
                        {
                            foreach (var identifierName in pooledIdentifiers.Item.IdentifierNames)
                            {
                                var argSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken);
                                if (symbol.Equals(argSymbol))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        internal static bool IsMemberDisposed(ISymbol member, IMethodSymbol disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (member == null ||
                disposeMethod == null)
            {
                return(false);
            }

            foreach (var reference in disposeMethod.DeclaringSyntaxReferences)
            {
                var node = reference.GetSyntax(cancellationToken) as MethodDeclarationSyntax;
                using (var pooled = DisposeWalker.Create(disposeMethod, semanticModel, cancellationToken))
                {
                    foreach (var invocation in pooled.Item)
                    {
                        if (IsDisposing(invocation, member, semanticModel, cancellationToken))
                        {
                            return(true);
                        }
                    }
                }

                using (var pooled = IdentifierNameWalker.Create(node))
                {
                    foreach (var identifier in pooled.Item.IdentifierNames)
                    {
                        var memberAccess = identifier.Parent as MemberAccessExpressionSyntax;
                        if (memberAccess?.Expression is BaseExpressionSyntax)
                        {
                            var baseMethod = semanticModel.GetSymbolSafe(identifier, cancellationToken) as IMethodSymbol;
                            if (baseMethod?.Name == "Dispose")
                            {
                                if (IsMemberDisposed(member, baseMethod, semanticModel, cancellationToken))
                                {
                                    return(true);
                                }
                            }
                        }

                        if (identifier.Identifier.ValueText != member.Name)
                        {
                            continue;
                        }

                        var symbol = semanticModel.GetSymbolSafe(identifier, cancellationToken);
                        if (member.Equals(symbol) || (member as IPropertySymbol)?.OverriddenProperty?.Equals(symbol) == true)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
            private static bool IsInitializedWithOther(BasePropertyDeclarationSyntax x, BasePropertyDeclarationSyntax y, out int result)
            {
                bool IsInitializedWith(EqualsValueClauseSyntax initializer, PropertyDeclarationSyntax other)
                {
                    using (var identifiers = IdentifierNameWalker.Borrow(initializer))
                    {
                        foreach (var identifier in identifiers.IdentifierNames)
                        {
                            if (identifier.Identifier.ValueText == other.Identifier.ValueText)
                            {
                                if (identifier.Parent is MemberAccessExpressionSyntax memberAccess &&
                                    memberAccess.Expression is IdentifierNameSyntax typeIdentifier &&
                                    other.Parent is TypeDeclarationSyntax typeDeclarationSyntax &&
                                    typeIdentifier.Identifier.ValueText != typeDeclarationSyntax.Identifier.ValueText)
                                {
                                    continue;
                                }

                                return(true);
                            }
                        }
                    }

                    return(false);
                }

                if (x is PropertyDeclarationSyntax xDeclaration &&
                    y is PropertyDeclarationSyntax yDeclaration &&
                    xDeclaration.Parent == yDeclaration.Parent)
                {
                    if (xDeclaration.Initializer is EqualsValueClauseSyntax xi &&
                        IsInitializedWith(xi, yDeclaration))
                    {
                        result = 1;
                        return(true);
                    }

                    if (yDeclaration.Initializer is EqualsValueClauseSyntax yi &&
                        IsInitializedWith(yi, xDeclaration))
                    {
                        result = -1;
                        return(true);
                    }
                }

                result = 0;
                return(false);
            }
        private static bool IsDisposedBefore(ISymbol symbol, ExpressionSyntax assignment, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            using (var pooled = InvocationWalker.Create(assignment.FirstAncestorOrSelf <MemberDeclarationSyntax>()))
            {
                foreach (var invocation in pooled.Item.Invocations)
                {
                    if (invocation.IsBeforeInScope(assignment) != Result.Yes)
                    {
                        continue;
                    }

                    var invokedSymbol = semanticModel.GetSymbolSafe(invocation, cancellationToken);
                    if (invokedSymbol?.Name != "Dispose")
                    {
                        continue;
                    }

                    var statement = invocation.FirstAncestorOrSelf <StatementSyntax>();
                    if (statement != null)
                    {
                        using (var pooledNames = IdentifierNameWalker.Create(statement))
                        {
                            foreach (var identifierName in pooledNames.Item.IdentifierNames)
                            {
                                var otherSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken);
                                if (symbol.Equals(otherSymbol))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
        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);
        }