Exemple #1
0
        /// <summary>
        /// Recursively mutates a single SyntaxNode
        /// </summary>
        /// <param name="currentNode">The current root node</param>
        /// <returns>Mutated node</returns>
        public override SyntaxNode Mutate(SyntaxNode input)
        {
            var mutationContext = new MutationContext(this);
            var mutation        = Mutate(input, mutationContext);

            return(mutation);
        }
        private SyntaxNode MutateExpression(SyntaxNode currentNode, MutationContext context)
        {
            // Nothing to mutate, dig further
            var childCopy = currentNode.TrackNodes(currentNode.ChildNodes().ToList().Append(currentNode));
            var mutated   = false;

            foreach (var child in currentNode.ChildNodes().ToList())
            {
                var mutatedChild = Mutate(child, context);
                if (child != mutatedChild)
                {
                    var currentChild = childCopy.GetCurrentNode(child);
                    childCopy = childCopy.ReplaceNode(currentChild, mutatedChild);
                    mutated   = true;
                }
            }

            if (currentNode is ExpressionSyntax expression && !expression.ContainsDeclarations())
            {
                childCopy = MutateSubExpressionWithConditional(expression, (ExpressionSyntax)childCopy, context);
                mutated   = true;
            }

            return(mutated ? childCopy : currentNode);
        }
        private SyntaxNode MutateForStatement(ForStatementSyntax forStatement, MutationContext context)
        {
            // for needs special treatments for its incrementors
            StatementSyntax forWithMutantIncrementors = forStatement.TrackNodes(forStatement);

            foreach (var incrementor in forStatement.Incrementors)
            {
                forWithMutantIncrementors = MutateSubExpressionWithIfStatements(forStatement, forWithMutantIncrementors, incrementor, context);
            }

            var originalFor = forWithMutantIncrementors.GetCurrentNode(forStatement);

            // mutate condition, if any
            ForStatementSyntax mutatedFor;
            StatementSyntax    statementPart;

            if (forStatement.Condition == null)
            {
                mutatedFor    = forStatement;
                statementPart = forStatement.Statement;
            }
            else
            {
                mutatedFor = forStatement.TrackNodes(forStatement.Condition, forStatement.Statement);
                mutatedFor = mutatedFor.ReplaceNode(mutatedFor.GetCurrentNode(forStatement.Condition),
                                                    Mutate(forStatement.Condition, context));
                statementPart = mutatedFor.GetCurrentNode(forStatement.Statement);
            }

            // mutate the statement/block
            mutatedFor = mutatedFor.ReplaceNode(statementPart, Mutate(forStatement.Statement, context));
            // and now we replace it
            return(forWithMutantIncrementors.ReplaceNode(originalFor, mutatedFor));
        }
        // recursive version
        public SyntaxNode Mutate(SyntaxNode currentNode, MutationContext context)
        {
            // don't mutate immutable nodes
            if (!SyntaxHelper.CanBeMutated(currentNode))
            {
                return(currentNode);
            }

            // search for node specific handler
            var nodeHandler = _specificOrchestrator.FindHandler(currentNode);

            return(nodeHandler.Mutate(currentNode, context));
        }
        public IEnumerable <Mutant> GenerateMutationsForNode(SyntaxNode current, MutationContext context)
        {
            var mutations = new List <Mutant>();

            foreach (var mutator in Mutators)
            {
                foreach (var mutation in mutator.Mutate(current, _options))
                {
                    var id = MutantCount;
                    Logger.LogDebug("Mutant {0} created {1} -> {2} using {3}", id, mutation.OriginalNode,
                                    mutation.ReplacementNode, mutator.GetType());
                    var newMutant = new Mutant
                    {
                        Id            = id,
                        Mutation      = mutation,
                        ResultStatus  = MutantStatus.NotRun,
                        IsStaticValue = context.InStaticValue
                    };
                    var duplicate = false;
                    // check if we have a duplicate
                    foreach (var mutant in Mutants)
                    {
                        if (mutant.Mutation.OriginalNode != mutation.OriginalNode ||
                            !SyntaxFactory.AreEquivalent(mutant.Mutation.ReplacementNode, newMutant.Mutation.ReplacementNode))
                        {
                            continue;
                        }
                        Logger.LogDebug($"Mutant {id} discarded as it is a duplicate of {mutant.Id}");
                        duplicate = true;
                        break;
                    }

                    if (duplicate)
                    {
                        continue;
                    }

                    Mutants.Add(newMutant);
                    MutantCount++;
                    mutations.Add(newMutant);
                }
            }

            return(mutations);
        }
        /// <summary>
        /// Recursively mutates a single SyntaxNode
        /// </summary>
        /// <param name="currentNode">The current root node</param>
        /// <returns>Mutated node</returns>
        public override SyntaxNode Mutate(SyntaxNode input)
        {
            var mutationContext = new MutationContext(this);
            var mutation        = Mutate(input, mutationContext);

            if (mutationContext.HasStatementLevelMutant && _options?.DevMode == true)
            {
                // some mutants where not injected for some reason, they should be reviewed to understand why.
                Logger.LogError($"Several mutants were not injected in the project : {mutationContext.BlockLevelControlledMutations.Count + mutationContext.StatementLevelControlledMutations.Count}");
            }
            // mark remaining mutants as CompileError
            foreach (var mutant in mutationContext.StatementLevelControlledMutations.Union(mutationContext.BlockLevelControlledMutations))
            {
                mutant.ResultStatus       = MutantStatus.CompileError;
                mutant.ResultStatusReason = "Stryker was not able to inject mutation in code.";
            }
            return(mutation);
        }
        private SyntaxNode MutateIfStatement(IfStatementSyntax ifStatement, MutationContext context)
        {
            var mutatedIf = ifStatement.Else != null
                ? ifStatement.TrackNodes(ifStatement.Condition, ifStatement.Statement, ifStatement.Else)
                : ifStatement.TrackNodes(ifStatement.Condition, ifStatement.Statement);

            var mutated = false;

            if (!ifStatement.Condition.ContainsDeclarations())
            {
                var currentCondition = mutatedIf.GetCurrentNode(ifStatement.Condition);
                var mutatedCondition = Mutate(ifStatement.Condition, context);
                if (mutatedCondition != currentCondition)
                {
                    mutatedIf = mutatedIf.ReplaceNode(currentCondition, mutatedCondition);
                    mutated   = true;
                }
            }

            if (ifStatement.Else != null)
            {
                var currentElse = mutatedIf.GetCurrentNode(ifStatement.Else);
                var mutatedElse = Mutate(ifStatement.Else, context);
                if (mutatedElse != currentElse)
                {
                    mutatedIf = mutatedIf.ReplaceNode(currentElse, mutatedElse);
                    mutated   = true;
                }
            }

            var currentStatement = mutatedIf.GetCurrentNode(ifStatement.Statement);
            var mutatedStatement = Mutate(ifStatement.Statement, context);

            if (currentStatement != mutatedStatement)
            {
                mutatedIf = mutatedIf.ReplaceNode(currentStatement, mutatedStatement);
                mutated   = true;
            }
            return(mutated ? mutatedIf : ifStatement);
        }
        private SyntaxNode Mutate(SyntaxNode currentNode, MutationContext context)
        {
            // don't mutate immutable nodes
            if (!SyntaxHelper.CanBeMutated(currentNode))
            {
                return(currentNode);
            }

            // identify static related structure
            switch (currentNode)
            {
            // static fields
            case FieldDeclarationSyntax fieldDeclaration when fieldDeclaration.Modifiers.Any(x => x.Kind() == SyntaxKind.StaticKeyword):
                context = new MutationContext
                {
                    InStaticValue = true
                };
                break;

            // static constructors
            case ConstructorDeclarationSyntax constructorDeclaration when constructorDeclaration.Modifiers.Any(x => x.Kind() == SyntaxKind.StaticKeyword):
                context = new MutationContext
                {
                    InStaticValue = true
                };
                if (MustInjectCoverageLogic)
                {
                    return(MutateStaticConstructor(constructorDeclaration, context));
                }
                break;

            // static properties
            case PropertyDeclarationSyntax propertyDeclaration when propertyDeclaration.Modifiers.Any(x => x.Kind() == SyntaxKind.StaticKeyword) && propertyDeclaration.AccessorList != null:
                context = new MutationContext
                {
                    InStaticValue = true
                };
                if (MustInjectCoverageLogic)
                {
                    return(MutateStaticAccessor(propertyDeclaration, context));
                }
                break;
            }

            switch (currentNode)
            {
            // apply statement specific strategies (where applicable)
            case ExpressionStatementSyntax tentativeAssignment when tentativeAssignment.Expression is AssignmentExpressionSyntax assign:
                return(MutateAssignment(tentativeAssignment, assign, context));

            case ExpressionStatementSyntax tentativeAssignment when tentativeAssignment.Expression is PostfixUnaryExpressionSyntax || tentativeAssignment.Expression is PrefixUnaryExpressionSyntax:
                return(MutateUnaryStatement(tentativeAssignment, context));

            case ExpressionStatementSyntax expressionStatement:
                // we must skip the expression statement part
                return(currentNode.ReplaceNode(expressionStatement.Expression, Mutate(expressionStatement.Expression, context)));

            case IfStatementSyntax ifStatement:
                return(MutateIfStatement(ifStatement, context));

            case ForStatementSyntax forStatement:
                return(MutateForStatement(forStatement, context));
            }

            var mutatedNode = MutateExpression(currentNode, context);

            return(AddReturnDefault(mutatedNode));
        }
        /// <summary>
        /// Mutates one single SyntaxNode using a mutator
        /// </summary>
        private IEnumerable <Mutant> ApplyMutator(SyntaxNode syntaxNode, IMutator mutator, MutationContext context)
        {
            var mutations = mutator.Mutate(syntaxNode);

            foreach (var mutation in mutations)
            {
                Logger.LogDebug("Mutant {0} created {1} -> {2} using {3}", MutantCount, mutation.OriginalNode, mutation.ReplacementNode, mutator.GetType());
                yield return(new Mutant()
                {
                    Id = MutantCount++,
                    Mutation = mutation,
                    ResultStatus = MutantStatus.NotRun,
                    IsStaticValue = context.InStaticValue
                });
            }
        }
 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 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 IEnumerable <Mutant> FindMutants(SyntaxNode current, MutationContext context)
 {
     return(Mutators.SelectMany(mutator => ApplyMutator(current, mutator, context)));
 }
        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 SyntaxNode MutateAssignment(ExpressionStatementSyntax tentativeAssignment, AssignmentExpressionSyntax assign, MutationContext context)
        {
            var expressionCopy = tentativeAssignment.TrackNodes(tentativeAssignment, assign, assign.Right);
            // mutate +=, *=, ...
            var result = MutateSubExpressionWithIfStatements(tentativeAssignment, expressionCopy, assign, context);

            // mutate the part right to the equal sign
            return(result.ReplaceNode(result.GetCurrentNode(assign.Right), Mutate(assign.Right, context)));
        }
        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);
        }
        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);
        }
        private SyntaxNode MutateUnaryStatement(ExpressionStatementSyntax expressionStatement, MutationContext context)
        {
            var expressionCopy = expressionStatement.TrackNodes(expressionStatement, expressionStatement.Expression);

            return(MutateSubExpressionWithIfStatements(expressionStatement, expressionCopy, expressionStatement.Expression, context));
        }
Exemple #19
0
 private MutationContext(MutationContext parent)
 {
     _ancestor         = parent;
     _mainOrchestrator = parent._mainOrchestrator;
     InStaticValue     = parent.InStaticValue;
 }