Пример #1
0
        public static bool IsAccessOnNewlyCreatedObject(KnownSymbols knownSymbols,
                                                        SemanticModel semanticModel,
                                                        SyntaxNode node, RecursiveState recursiveState1)
        {
            bool IsOnNewlyCreatedObject(ExpressionSyntax exp)
            {
                if (exp is MemberAccessExpressionSyntax memberAccess1)
                {
                    return(IsOnNewlyCreatedObject(memberAccess1.Expression));
                }
                if (exp is ElementAccessExpressionSyntax elementAccess1)
                {
                    return(IsOnNewlyCreatedObject(elementAccess1.Expression));
                }
                return(Utils.IsNewlyCreatedObject(semanticModel, exp, knownSymbols, RecursiveIsNewlyCreatedObjectState.Empty(), recursiveState1));
            }

            if (node.Parent is MemberAccessExpressionSyntax memberAccess)
            {
                return(IsOnNewlyCreatedObject(memberAccess));
            }

            if (node is ElementAccessExpressionSyntax elementAccess)
            {
                return(IsOnNewlyCreatedObject(elementAccess));
            }

            return(false);
        }
Пример #2
0
        ChangeAcceptedPurityTypeBasedOnWhetherExpressionRepresentsANewObjectOrParameterBasedExpression(
            PurityType currentAcceptedPurityType,
            ExpressionSyntax node,
            KnownSymbols knownSymbols,
            SemanticModel semanticModel,
            RecursiveState recursiveState)
        {
            if (Utils.IsNewlyCreatedObject(semanticModel, node, knownSymbols, RecursiveIsNewlyCreatedObjectState.Empty(), recursiveState))
            {
                return(PurityType.PureExceptLocally);
            }
            else if (ImpuritiesFinder.IsParameter(semanticModel, node))
            {
                return(PurityType.PureExceptReadLocally);
            }

            return(currentAcceptedPurityType);
        }
Пример #3
0
        public static IEnumerable <ExpressionSyntax> GetNonNewObjectReturnsForPropertyGet(
            PropertyDeclarationSyntax propertyDeclaration,
            SemanticModel semanticModel,
            KnownSymbols knownSymbols,
            RecursiveState recursiveState1)
        {
            var propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration);

            if (propertySymbol.GetMethod == null)
            {
                yield break;
            }

            if (!propertySymbol.ReturnsByRef && IsCompleteValueType(propertySymbol.Type))
            {
                yield break;
            }

            List <ExpressionSyntax> returnExpressions;

            if (propertyDeclaration.AccessorList != null)
            {
                var getAccessor =
                    propertyDeclaration.AccessorList.Accessors.FirstOrNoValue(x =>
                                                                              x.Keyword.Kind() == SyntaxKind.GetKeyword);

                if (getAccessor.HasNoValue)
                {
                    yield break;
                }

                var getAccessorValue = getAccessor.GetValue();

                returnExpressions =
                    getAccessorValue.ExpressionBody != null
                        ? new List <ExpressionSyntax>()
                {
                    getAccessorValue.ExpressionBody.Expression
                }
                        : getAccessor.GetValue()
                .DescendantNodes()
                .OfType <ReturnStatementSyntax>()
                .Select(x => x.Expression)
                .ToList();
            }
            else if (propertyDeclaration.ExpressionBody != null)
            {
                returnExpressions = new List <ExpressionSyntax>()
                {
                    propertyDeclaration.ExpressionBody.Expression
                };
            }
            else
            {
                yield break;
            }

            foreach (var expression in returnExpressions)
            {
                if (!Utils.IsNewlyCreatedObject(semanticModel, expression, knownSymbols, RecursiveIsNewlyCreatedObjectState.Empty(), recursiveState1))
                {
                    yield return(expression);
                }
            }
        }
Пример #4
0
        public static IEnumerable <ExpressionSyntax> GetNonNewObjectReturnsForMethod(
            BaseMethodDeclarationSyntax methodDeclaration,
            SemanticModel semanticModel,
            KnownSymbols knownSymbols, RecursiveState recursiveState1)
        {
            var methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration);

            if (!methodSymbol.ReturnsByRef && IsCompleteValueType(methodSymbol.ReturnType))
            {
                yield break;
            }

            var returnExpressions =
                methodDeclaration.Body != null
                    ? methodDeclaration.Body
                .DescendantNodes()
                .OfType <ReturnStatementSyntax>()
                .Select(x => x.Expression)
                .ToArray()
                    : new[] { methodDeclaration.ExpressionBody.Expression };

            foreach (var expression in returnExpressions)
            {
                if (!Utils.IsNewlyCreatedObject(semanticModel, expression, knownSymbols, RecursiveIsNewlyCreatedObjectState.Empty(), recursiveState1))
                {
                    yield return(expression);
                }
            }
        }
Пример #5
0
        public static bool IsNewlyCreatedObject(SemanticModel semanticModel,
                                                SyntaxNode expression,
                                                KnownSymbols knownSymbols,
                                                RecursiveIsNewlyCreatedObjectState recursiveState, RecursiveState recursiveState1)
        {
            if (expression is LiteralExpressionSyntax)
            {
                return(true);
            }

            if (expression is TupleExpressionSyntax tuple)
            {
                return(tuple.Arguments
                       .Select(x => x.Expression)
                       .All(x => IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState, recursiveState1)));
            }


            if (expression is ObjectCreationExpressionSyntax objectCreationExpression)
            {
                if (objectCreationExpression
                    .ArgumentList != null)
                {
                    if (objectCreationExpression
                        .ArgumentList
                        .Arguments.Any(arg =>
                                       !IsNewlyCreatedObject(semanticModel, arg.Expression, knownSymbols, recursiveState, recursiveState1)))
                    {
                        return(false);
                    }
                }


                if (objectCreationExpression.Initializer != null)
                {
                    if (objectCreationExpression
                        .Initializer
                        .Expressions
                        .OfType <AssignmentExpressionSyntax>()
                        .Any(x =>
                             !IsNewlyCreatedObject(semanticModel, x.Right, knownSymbols, recursiveState, recursiveState1)))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            if (expression is ArrayCreationExpressionSyntax arrayCreationExpression)
            {
                if (arrayCreationExpression.Initializer != null)
                {
                    if (arrayCreationExpression
                        .Initializer
                        .Expressions
                        .Any(x =>
                             !IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState, recursiveState1)))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            if (expression is ImplicitArrayCreationExpressionSyntax arrayCreationExpression1)
            {
                if (arrayCreationExpression1.Initializer != null)
                {
                    if (arrayCreationExpression1
                        .Initializer
                        .Expressions
                        .Any(x =>
                             !IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState, recursiveState1)))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            if (expression is InitializerExpressionSyntax initSyntax &&
                initSyntax.Kind() == SyntaxKind.ArrayInitializerExpression)
            {
                if (initSyntax
                    .Expressions
                    .Any(x =>
                         !IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState, recursiveState1)))
                {
                    return(false);
                }
                return(true);
            }

            if (expression is InvocationExpressionSyntax invocationExpression)
            {
                if (semanticModel.GetSymbolInfo(invocationExpression.Expression).Symbol is IMethodSymbol invokedMethod)
                {
                    if (MethodReturnsNewObject(semanticModel, knownSymbols, recursiveState1, invokedMethod))
                    {
                        return(true);
                    }
                }
            }

            if (expression is MemberAccessExpressionSyntax memberAccessExpression)
            {
                if (semanticModel.GetSymbolInfo(memberAccessExpression.Name).Symbol is IPropertySymbol propertySymbol && !GetUsage(memberAccessExpression.Name).IsWrite())
                {
                    if (MethodReturnsNewObject(semanticModel, knownSymbols, recursiveState1, propertySymbol.GetMethod))
                    {
                        return(true);
                    }
                }
            }

            if (expression is IdentifierNameSyntax identifier)
            {
                var identifierSymbol = semanticModel.GetSymbolInfo(identifier).Symbol;

                if (identifierSymbol is ILocalSymbol local)
                {
                    if (!local.IsRef && IsCompleteValueType(local.Type))
                    {
                        return(true);
                    }

                    if (recursiveState.VariablesUnderTest.Contains(local))
                    {
                        return(true);
                    }

                    var methodBody =
                        GetBodyOfMethodThatContainsExpression(expression);

                    if (methodBody.HasNoValue)
                    {
                        return(false);
                    }

                    var valuesInjectedIntoObject =
                        GetValuesPossiblyInjectedInto(semanticModel, local, methodBody.GetValue(), knownSymbols, recursiveState1);

                    if (!valuesInjectedIntoObject.All(x =>
                    {
                        var typeSymbol = semanticModel.GetTypeInfo(x).Type;

                        if (typeSymbol != null && IsImmutablePureData(typeSymbol))
                        {
                            return(true);
                        }

                        return(IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState.Add(local),
                                                    recursiveState1));
                    }))
                    {
                        return(false);
                    }

                    return(FindValuesAssignedToVariable(semanticModel, local, methodBody.GetValue()).All(x =>
                                                                                                         IsNewlyCreatedObject(semanticModel, x, knownSymbols, recursiveState.Add(local), recursiveState1)));
                }
            }

            if (semanticModel.GetTypeInfo(expression).Type is ITypeSymbol type)
            {
                if (IsCompleteValueType(type))
                {
                    return(true);
                }
            }

            return(false);
        }