private SyntaxNode MutateStaticConstructor(ConstructorDeclarationSyntax constructorDeclaration, MutationContext context)
        {
            var trackedConstructor = constructorDeclaration.TrackNodes((SyntaxNode)constructorDeclaration.Body ?? constructorDeclaration.ExpressionBody);

            if (constructorDeclaration.ExpressionBody != null)
            {
                var bodyBlock   = SyntaxFactory.Block(SyntaxFactory.ExpressionStatement(constructorDeclaration.ExpressionBody.Expression));
                var markedBlock = MutantPlacer.PlaceStaticContextMarker((BlockSyntax)Mutate(bodyBlock, context));
                trackedConstructor = trackedConstructor.Update(
                    trackedConstructor.AttributeLists,
                    trackedConstructor.Modifiers,
                    trackedConstructor.Identifier,
                    trackedConstructor.ParameterList,
                    trackedConstructor.Initializer,
                    markedBlock,
                    null,
                    SyntaxFactory.Token(SyntaxKind.None));
            }
            else if (constructorDeclaration.Body != null)
            {
                var markedBlock = MutantPlacer.PlaceStaticContextMarker((BlockSyntax)Mutate(constructorDeclaration.Body, context));
                trackedConstructor = trackedConstructor.ReplaceNode(trackedConstructor.GetCurrentNode(constructorDeclaration.Body), markedBlock);
            }

            return(trackedConstructor);
        }
Exemple #2
0
        private SyntaxNode MutateStaticConstructor(ConstructorDeclarationSyntax constructorDeclaration, MutationContext context)
        {
            var trackedConstructor = constructorDeclaration.TrackNodes(constructorDeclaration.Body);
            var mutatedBlock       = (BlockSyntax)Mutate(constructorDeclaration.Body, context);
            var markedBlock        = MutantPlacer.PlaceStaticContextMarker(mutatedBlock);

            return(trackedConstructor.ReplaceNode(trackedConstructor.Body, markedBlock));
        }
        private ExpressionSyntax MutateSubExpressionWithConditional(ExpressionSyntax originalNode, ExpressionSyntax currentNode, MutationContext context)
        {
            var expressionAst = currentNode;

            foreach (var mutant in FindMutants(originalNode, context))
            {
                expressionAst = MutantPlacer.PlaceWithConditionalExpression(expressionAst, ApplyMutant(originalNode, mutant), mutant.Id);
            }
            return(expressionAst);
        }
        private StatementSyntax MutateSubExpressionWithIfStatements(StatementSyntax originalNode, StatementSyntax nodeToReplace, SyntaxNode subExpression, MutationContext context)
        {
            var ast = nodeToReplace;

            // The mutations should be placed using an IfStatement
            foreach (var mutant in FindMutants(subExpression, context))
            {
                var mutatedNode = ApplyMutant(originalNode, mutant);
                ast = MutantPlacer.PlaceWithIfStatement(ast, mutatedNode, mutant.Id);
            }
            return(ast);
        }
        private SyntaxNode MutateWithConditionalExpressions(ExpressionSyntax currentNode)
        {
            var expressionAst = currentNode;

            foreach (var mutant in FindMutantsRecursive(currentNode))
            {
                _mutants.Add(mutant);
                var mutatedNode = ApplyMutant(currentNode, mutant);
                expressionAst = MutantPlacer.PlaceWithConditionalExpression(expressionAst, mutatedNode, mutant.Id);
            }
            return(expressionAst);
        }
 public static SyntaxNode RemoveMutant(SyntaxNode nodeToRemove)
 {
     // remove the mutated node using its MutantPlacer remove method and update the tree
     if (nodeToRemove is IfStatementSyntax ifStatement)
     {
         return(MutantPlacer.RemoveByIfStatement(ifStatement));
     }
     else if (nodeToRemove is ParenthesizedExpressionSyntax parenthesizedExpression)
     {
         return(MutantPlacer.RemoveByConditionalExpression(parenthesizedExpression));
     }
     // this is not one of our structure
     return(nodeToRemove);
 }
 /// <summary>
 /// Recursively mutates a single SyntaxNode
 /// </summary>
 /// <param name="currentNode">The current root node</param>
 /// <returns>Mutated node</returns>
 public SyntaxNode Mutate(SyntaxNode currentNode)
 {
     if (GetExpressionSyntax(currentNode) is var expressionSyntax && expressionSyntax != null)
     {
         // The mutations should be placed using a ConditionalExpression
         ExpressionSyntax expressionAst = expressionSyntax;
         foreach (var mutant in FindMutants(expressionSyntax))
         {
             _mutants.Add(mutant);
             ExpressionSyntax mutatedNode = ApplyMutant(expressionSyntax, mutant);
             expressionAst = MutantPlacer.PlaceWithConditionalExpression(expressionAst, mutatedNode, mutant.Id);
         }
         return(currentNode.ReplaceNode(expressionSyntax, expressionAst));
     }
        private SyntaxNode MutateWithConditionalExpressions(ExpressionSyntax currentNode)
        {
            var expressionAst = currentNode.TrackNodes(currentNode.ChildNodes().Append(currentNode));

            foreach (var childNode in currentNode.ChildNodes())
            {
                var mutatedChild = Mutate(childNode);
                if (mutatedChild != childNode)
                {
                    expressionAst = expressionAst.ReplaceNode(expressionAst.GetCurrentNode(childNode), mutatedChild);
                }
            }
            foreach (var mutant in FindMutants(currentNode))
            {
                var mutatedNode = ApplyMutant(currentNode, mutant);
                expressionAst = MutantPlacer.PlaceWithConditionalExpression(expressionAst, mutatedNode, mutant.Id);
            }
            return(expressionAst);
        }
        private SyntaxNode MutateStaticAccessor(PropertyDeclarationSyntax accessorDeclaration, MutationContext context)
        {
            var trackedNode = accessorDeclaration.TrackNodes(accessorDeclaration.AccessorList.Accessors.Select(x => (SyntaxNode)x.Body ?? x.ExpressionBody).Where(x => x != null));

            foreach (var accessor in accessorDeclaration.AccessorList.Accessors)
            {
                if (accessor.ExpressionBody != null)
                {
                    var markedBlock = Mutate(accessor.ExpressionBody, context);
                    trackedNode = trackedNode.ReplaceNode(trackedNode.GetCurrentNode(accessor.ExpressionBody), markedBlock);
                }
                else if (accessor.Body != null)
                {
                    var markedBlock = MutantPlacer.PlaceStaticContextMarker((BlockSyntax)Mutate(accessor.Body, context));
                    trackedNode = trackedNode.ReplaceNode(trackedNode.GetCurrentNode(accessor.Body), markedBlock);
                }
            }

            return(trackedNode);
        }
        /// <summary>
        /// Add return default to the end of the method to prevent "not all code paths return a value" error as a result of mutations
        /// </summary>
        private SyntaxNode AddReturnDefault(SyntaxNode currentNode)
        {
            // If it's not a method or the method has no body skip the node
            if (!(currentNode is MethodDeclarationSyntax methodNode) || methodNode.Body == null)
            {
                return(currentNode);
            }

            // If method return type is void skip the node
            if (methodNode.ReturnType is PredefinedTypeSyntax predefinedType && predefinedType.Keyword.IsKind(SyntaxKind.VoidKeyword))
            {
                return(currentNode);
            }

            TypeSyntax returnType = methodNode.ReturnType;

            // the GenericNameSyntax node can be encapsulated by QualifiedNameSyntax nodes
            var genericReturn = returnType.DescendantNodesAndSelf().OfType <GenericNameSyntax>().FirstOrDefault();

            if (methodNode.Modifiers.Any(x => x.IsKind(SyntaxKind.AsyncKeyword)))
            {
                if (genericReturn != null)
                {
                    // if the method is async and returns a generic task, make the return default return the underlying type
                    returnType = genericReturn.TypeArgumentList.Arguments.First();
                }
                else
                {
                    // if the method is async but returns a non-generic task, don't add the return default
                    return(currentNode);
                }
            }

            var newBody = methodNode.Body.AddStatements(MutantPlacer.AnnotateHelper(SyntaxFactory.ReturnStatement(SyntaxFactory.DefaultExpression(returnType))));

            currentNode = currentNode.ReplaceNode(methodNode.Body, newBody);

            return(currentNode);
        }
 private ExpressionSyntax MutateSubExpressionWithConditional(ExpressionSyntax originalNode, ExpressionSyntax currentNode, MutationContext context)
 {
     return(FindMutants(originalNode, context).Aggregate(currentNode, (current, mutant) => MutantPlacer.PlaceWithConditionalExpression(current, ApplyMutant(originalNode, mutant), mutant.Id)));
 }
        private SyntaxNode MutateExpressions(SyntaxNode currentNode)
        {
            if (currentNode is ExpressionStatementSyntax expressionStatement)
            {
                // The subExpression of a ExpressionStatement cannot be mutated directly
                var mutant = Mutate(expressionStatement.Expression);
                return(currentNode.ReplaceNode(expressionStatement.Expression, mutant));
            }
            if (currentNode is InvocationExpressionSyntax invocationExpression && invocationExpression.ArgumentList.Arguments.Count == 0)
            {
                var mutant = FindMutants(invocationExpression).FirstOrDefault();
                if (mutant != null)
                {
                    _mutants.Add(mutant);
                    return(MutantPlacer.PlaceWithConditionalExpression(invocationExpression, mutant.Mutation.ReplacementNode as ExpressionSyntax, mutant.Id));
                }
            }
            var expressions = GetExpressionSyntax(currentNode).Where(x => x != null);

            if (expressions.Any())
            {
                var currentNodeCopy = currentNode.TrackNodes(expressions);
                foreach (var expressionSyntax in expressions)
                {
                    var currentExpressionSyntax = currentNodeCopy.GetCurrentNode(expressionSyntax);
                    if (expressionSyntax is InvocationExpressionSyntax)
                    {
                        // chained invocations, we will recurse
                        var mutant = Mutate(expressionSyntax);
                        currentNodeCopy = currentNodeCopy.ReplaceNode(currentExpressionSyntax, mutant);
                        continue;
                    }
                    SyntaxNode mutationCandidate = null;

                    if (expressionSyntax is ParenthesizedLambdaExpressionSyntax lambda)
                    {
                        mutationCandidate = lambda.Body;
                    }
                    else if (expressionSyntax is MemberAccessExpressionSyntax memberAccess)
                    {
                        mutationCandidate = memberAccess.Expression;
                    }
                    else if (expressionSyntax is AnonymousFunctionExpressionSyntax anonymousFunction)
                    {
                        mutationCandidate = anonymousFunction.Body;
                    }

                    if (mutationCandidate != null)
                    {
                        // we can  mutate a part of expression
                        var subNodeCopy = expressionSyntax.TrackNodes(mutationCandidate);
                        var sub         = subNodeCopy.ReplaceNode(subNodeCopy.GetCurrentNode(mutationCandidate), Mutate(mutationCandidate));
                        currentNodeCopy = currentNodeCopy.ReplaceNode(currentExpressionSyntax, sub);
                    }
                    else
                    {
                        // attempts to mutate the expression as a whole
                        currentNodeCopy = currentNodeCopy.ReplaceNode(currentExpressionSyntax,
                                                                      MutateWithConditionalExpressions(expressionSyntax));
                    }
                }

                return(currentNodeCopy);
            }

            return(null);
        }