protected override LocalFunctionStatementSyntax InjectMutations(LocalFunctionStatementSyntax sourceNode, LocalFunctionStatementSyntax targetNode, MutationContext context) { // find out parameters targetNode = base.InjectMutations(sourceNode, targetNode, context); var fullTargetBody = targetNode.Body; var sourceNodeParameterList = sourceNode.ParameterList; if (fullTargetBody != null) { // the function is in the body form // inject initialization to default for all out parameters targetNode = sourceNode.WithBody(MutantPlacer.AddDefaultInitializers(fullTargetBody, sourceNodeParameterList.Parameters.Where(p => p.Modifiers.Any(m => m.Kind() == SyntaxKind.OutKeyword)))); // add a return in case we changed the control flow return(MutantPlacer.AddEndingReturn(targetNode)); } // nothing to do if there is now pending statement mutations if (!context.HasStatementLevelMutant) { return(targetNode); } // we need to move to a body version of the function to inject pending mutations targetNode = MutantPlacer.ConvertExpressionToBody(targetNode); return(targetNode.WithBody(SyntaxFactory.Block(context.InjectBlockLevelExpressionMutation(targetNode.Body, sourceNode.ExpressionBody.Expression, sourceNode.NeedsReturn())))); }
public void ShouldInjectInitializersAndRestore() { var source = "class Test {bool Method(out int x) {x=0;}}"; var expected = "class Test {bool Method(out int x) {{x = default(int);}x=0;}}"; CheckMutantPlacerProperlyPlaceAndRemoveHelpers <BlockSyntax>(source, expected, (n) => MutantPlacer.AddDefaultInitializers(n, new[] { SyntaxFactory.Parameter(SyntaxFactory.Identifier("x")).WithType(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)) ) })); }
protected override AnonymousFunctionExpressionSyntax InjectMutations(AnonymousFunctionExpressionSyntax sourceNode, AnonymousFunctionExpressionSyntax targetNode, MutationContext context) { targetNode = base.InjectMutations(sourceNode, targetNode, context); if (targetNode.Block == null) { if (targetNode.ExpressionBody == null) { // only a definition (eg interface) return(targetNode); } // this is an expression body method if (!context.HasStatementLevelMutant) { // there is no statement or block level mutant, so the method control flow is not changed by mutations // there is no need to change the method in any may return(targetNode); } // we need to convert it to expression body form targetNode = MutantPlacer.ConvertExpressionToBody(targetNode); // we need to inject pending block (and statement) level mutations targetNode = targetNode.WithBody( SyntaxFactory.Block(context.InjectBlockLevelExpressionMutation(targetNode.Block, sourceNode.ExpressionBody, true))); } else { // we add an ending return, just in case targetNode = MutantPlacer.AddEndingReturn(targetNode); } if (targetNode is SimpleLambdaExpressionSyntax lambdaExpression && lambdaExpression.Parameter.Modifiers.Any(m => m.Kind() == SyntaxKind.OutKeyword)) { targetNode = targetNode.WithBody(MutantPlacer.AddDefaultInitializers(targetNode.Block, new List <ParameterSyntax> { lambdaExpression.Parameter })); }
/// <inheritdoc/> /// Inject mutations and convert expression body to block body if required. protected override BaseMethodDeclarationSyntax InjectMutations(T sourceNode, BaseMethodDeclarationSyntax targetNode, MutationContext context) { targetNode = base.InjectMutations(sourceNode, targetNode, context); if (targetNode.Body == null) { if (targetNode.ExpressionBody == null) { // only a definition (eg interface) return(targetNode); } // this is an expression body method if (!context.HasStatementLevelMutant) { // there is no statement or block level mutant, so the method control flow is not changed by mutations // there is no need to change the method in any may return(targetNode); } // we need to convert it to expression body form targetNode = MutantPlacer.ConvertExpressionToBody(targetNode); // we need to inject pending block (and statement) level mutations targetNode = targetNode.WithBody( SyntaxFactory.Block(context.InjectBlockLevelExpressionMutation(targetNode.Body, sourceNode.ExpressionBody?.Expression, sourceNode.NeedsReturn()))); } else { // we add an ending return, just in case targetNode = MutantPlacer.AddEndingReturn(targetNode); } // inject initialization to default for all out parameters targetNode = targetNode.WithBody(MutantPlacer.AddDefaultInitializers(targetNode.Body, sourceNode.ParameterList.Parameters.Where(p => p.Modifiers.Any(m => m.Kind() == SyntaxKind.OutKeyword)))); return(targetNode); }