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 }