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); }
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); }
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); } } }
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); } } }
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); }