Esempio n. 1
0
        internal static bool IsAssignedAndDisposedInSetupAndTearDown(ISymbol fieldOrProperty, TypeDeclarationSyntax scope, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (fieldOrProperty == null)
            {
                return(false);
            }

            if (AssignmentWalker.SingleForSymbol(fieldOrProperty, scope, Search.TopLevel, semanticModel, cancellationToken, out var assignment) &&
                assignment.FirstAncestor <MethodDeclarationSyntax>() is MethodDeclarationSyntax methodDeclaration)
            {
                if (Attribute.TryGetAttribute(methodDeclaration, KnownSymbol.NUnitSetUpAttribute, semanticModel, cancellationToken, out _))
                {
                    if (fieldOrProperty.ContainingType.TryFirstMethodRecursive(
                            x => x.GetAttributes().Any(a => a.AttributeClass == KnownSymbol.NUnitTearDownAttribute),
                            out var tearDown))
                    {
                        return(RefCounter.IsMemberDisposed(fieldOrProperty, tearDown, semanticModel, cancellationToken));
                    }
                }

                if (Attribute.TryGetAttribute(methodDeclaration, KnownSymbol.NUnitOneTimeSetUpAttribute, semanticModel, cancellationToken, out _))
                {
                    if (fieldOrProperty.ContainingType.TryFirstMethodRecursive(
                            x => x.GetAttributes().Any(a => a.AttributeClass == KnownSymbol.NUnitOneTimeTearDownAttribute),
                            out var tearDown))
                    {
                        return(RefCounter.IsMemberDisposed(fieldOrProperty, tearDown, semanticModel, cancellationToken));
                    }
                }
            }

            return(false);
        }
Esempio n. 2
0
        internal static bool TryGetAssignment(this BlockSyntax body, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, List <AssignmentExpressionSyntax> result)
        {
            if (symbol == null)
            {
                return(false);
            }

            AssignmentWalker.AllWith(symbol, body, Search.TopLevel, semanticModel, cancellationToken, result);
            return(true);
        }
Esempio n. 3
0
        internal static bool TryGetAssignment(this BlockSyntax body, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out AssignmentExpressionSyntax result)
        {
            result = null;
            if (symbol == null)
            {
                return(false);
            }

            return(AssignmentWalker.FirstWith(symbol, body, Search.TopLevel, semanticModel, cancellationToken, out result));
        }
Esempio n. 4
0
        internal static bool IsAssignedInSetUp(ISymbol fieldOrProperty, TypeDeclarationSyntax scope, SemanticModel semanticModel, CancellationToken cancellationToken, out AttributeSyntax attribute)
        {
            if (AssignmentWalker.SingleForSymbol(fieldOrProperty, scope, Search.TopLevel, semanticModel, cancellationToken, out var assignment) &&
                assignment.FirstAncestor <MethodDeclarationSyntax>() is MethodDeclarationSyntax methodDeclaration)
            {
                return(Attribute.TryGetAttribute(methodDeclaration, KnownSymbol.NUnitSetUpAttribute, semanticModel, cancellationToken, out attribute) ||
                       Attribute.TryGetAttribute(methodDeclaration, KnownSymbol.NUnitOneTimeSetUpAttribute, semanticModel, cancellationToken, out attribute));
            }

            attribute = null;
            return(false);
        }
Esempio n. 5
0
        internal static bool AssignsSymbolInSetter(IPropertySymbol property, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            var setMethod = property?.SetMethod;

            if (setMethod == null ||
                setMethod.DeclaringSyntaxReferences.Length == 0)
            {
                return(false);
            }

            if (TryGetSetter(property, cancellationToken, out var setter))
            {
                if (AssignmentWalker.FirstForSymbol(symbol, setter, Search.Recursive, semanticModel, cancellationToken))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 6
0
        /// <summary>
        /// Check if any path returns a created IDisposable
        /// </summary>
        internal static Result IsAssignedWithCreated(ExpressionSyntax disposable, SemanticModel semanticModel, CancellationToken cancellationToken, out ISymbol assignedSymbol)
        {
            if (!IsPotentiallyAssignableTo(disposable, semanticModel, cancellationToken))
            {
                assignedSymbol = null;
                return(Result.No);
            }

            if (semanticModel.GetSymbolSafe(disposable, cancellationToken) is IPropertySymbol property &&
                property.TryGetSetter(cancellationToken, out var setter))
            {
                using (var pooledSet = PooledHashSet <ISymbol> .Borrow())
                {
                    using (var pooledAssigned = AssignmentWalker.Borrow(setter, Search.Recursive, semanticModel, cancellationToken))
                    {
                        foreach (var assigned in pooledAssigned.Assignments)
                        {
                            var symbol = semanticModel.GetSymbolSafe(assigned.Left, cancellationToken);
                            if (IsPotentiallyAssignableTo(assigned.Left, semanticModel, cancellationToken) &&
                                (symbol is IFieldSymbol ||
                                 symbol is IPropertySymbol))
                            {
                                pooledSet.Add(symbol).IgnoreReturnValue();
                            }
                        }
                    }

                    assignedSymbol = null;
                    var result = Result.No;
                    foreach (var symbol in pooledSet)
                    {
                        switch (IsAssignedWithCreated(symbol, disposable, semanticModel, cancellationToken))
                        {
                        case Result.Unknown:
                            if (result == Result.No)
                            {
                                assignedSymbol = symbol;
                                result         = Result.Unknown;
                            }

                            break;

                        case Result.Yes:
                            assignedSymbol = symbol;
                            return(Result.Yes);

                        case Result.AssumeYes:
                            assignedSymbol = symbol;
                            result         = Result.AssumeYes;
                            break;

                        case Result.No:
                        case Result.AssumeNo:
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }

                    return(result);
                }
            }

            using (var assignedValues = AssignedValueWalker.Borrow(disposable, semanticModel, cancellationToken))
            {
                assignedSymbol = assignedValues.CurrentSymbol;
                if (assignedValues.Count == 1 &&
                    disposable.Parent is AssignmentExpressionSyntax assignment &&
                    assignment.Parent is ParenthesizedExpressionSyntax parenthesizedExpression &&
                    parenthesizedExpression.Parent is BinaryExpressionSyntax binary &&
                    binary.IsKind(SyntaxKind.CoalesceExpression))
                {
                    return(Result.No);
                }

                using (var recursive = RecursiveValues.Create(assignedValues, semanticModel, cancellationToken))
                {
                    return(IsAnyCreation(recursive, semanticModel, cancellationToken));
                }
            }
        }