1 /**
2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved.
3 License: MPL-2
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 
6 This Source Code Form is subject to the terms of the Mozilla Public License,
7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain
8 one at http://mozilla.org/MPL/2.0/.
9 */
10 module dextool.plugin.mutate.backend.mutation_type;
11 
12 import dextool.plugin.mutate.backend.type;
13 import dextool.plugin.mutate.type : MutationKind;
14 
15 public import dextool.plugin.mutate.backend.mutation_type.abs;
16 public import dextool.plugin.mutate.backend.mutation_type.aor;
17 public import dextool.plugin.mutate.backend.mutation_type.cor;
18 public import dextool.plugin.mutate.backend.mutation_type.dcc;
19 public import dextool.plugin.mutate.backend.mutation_type.dcr;
20 public import dextool.plugin.mutate.backend.mutation_type.lcr;
21 public import dextool.plugin.mutate.backend.mutation_type.lcrb;
22 public import dextool.plugin.mutate.backend.mutation_type.ror;
23 public import dextool.plugin.mutate.backend.mutation_type.sdl;
24 public import dextool.plugin.mutate.backend.mutation_type.uoi;
25 
26 @safe:
27 
28 /** Expand a mutation to all kinds at the same mutation point that would result in the same mutation being performed.
29  */
30 Mutation.Kind[] broadcast(const Mutation.Kind k) {
31     switch (k) with (Mutation.Kind) {
32     case rorLT:
33         goto case;
34     case rorpLT:
35         return [rorLT, rorpLT];
36     case rorLE:
37         goto case;
38     case rorpLE:
39         return [rorLE, rorpLE];
40     case rorGT:
41         goto case;
42     case rorpGT:
43         return [rorGT, rorpGT];
44     case rorGE:
45         goto case;
46     case rorpGE:
47         return [rorGE, rorpGE];
48     case rorEQ:
49         goto case;
50     case rorpEQ:
51         return [rorEQ, rorpEQ];
52     case rorNE:
53         goto case;
54     case rorpNE:
55         return [rorNE, rorpNE];
56 
57     default:
58         return [k];
59     }
60 }
61 
62 Mutation.Kind[] toInternal(const MutationKind[] k) @safe pure nothrow {
63     import std.algorithm : map, joiner;
64     import std.array : array;
65     import std.traits : EnumMembers;
66 
67     auto kinds(const MutationKind k) {
68         final switch (k) with (MutationKind) {
69         case any:
70             return [EnumMembers!(Mutation.Kind)];
71         case ror:
72             return rorMutationsAll.dup;
73         case rorp:
74             return rorpMutationsAll.dup;
75         case lcr:
76             return lcrMutationsAll.dup;
77         case aor:
78             return aorMutationsAll.dup ~ aorAssignMutationsAll;
79         case uoi:
80             return uoiLvalueMutations;
81         case abs:
82             return absMutations;
83         case sdl:
84             return stmtDelMutations;
85         case cor:
86             return corMutationsRaw.dup;
87         case dcc:
88             return dccBranchMutationsRaw.dup ~ dccCaseMutationsRaw.dup;
89         case dcr:
90             return dccBranchMutationsRaw.dup ~ dcrCaseMutationsRaw.dup;
91         case lcrb:
92             return lcrbMutationsAll.dup ~ lcrbAssignMutationsAll.dup;
93         }
94     }
95 
96     return (k is null ? [MutationKind.any] : k).map!(a => kinds(a)).joiner.array;
97 }
98 
99 /// Convert the internal mutation kind to those that are presented to the user via the CLI.
100 MutationKind toUser(Mutation.Kind k) @safe nothrow {
101     return fromInteralKindToUserKind[k];
102 }
103 
104 private:
105 
106 immutable MutationKind[Mutation.Kind] fromInteralKindToUserKind;
107 
108 shared static this() {
109     import std.traits : EnumMembers;
110 
111     static foreach (const user_kind; EnumMembers!MutationKind) {
112         foreach (const internal_kind; toInternal([user_kind])) {
113             fromInteralKindToUserKind[internal_kind] = user_kind;
114         }
115     }
116 }