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 #SPC-plugin_mutate_mutation_ror 11 */ 12 module dextool.plugin.mutate.backend.mutation_type.ror; 13 14 import dextool.plugin.mutate.backend.type; 15 import dextool.clang_extensions : OpKind; 16 17 /** Produce the mutations that can be applied on an operator. 18 * 19 * Params: 20 * op = the c/c++ operator in the AST 21 * tyi = type info about the expressions on the sides of the operator 22 * 23 * The resulting schema is intended to be: 24 * normal + pointer - float - enum - bool 25 * 26 * The schema when used is: 27 * ror = normal - float - enum - bool 28 * rorp = pointer - float - enum - bool 29 * 30 * See SPC-plugin_mutate_mutation_ror for the subsumed table. 31 */ 32 auto rorMutations(const OpKind op, const OpTypeInfo tyi) @safe pure nothrow { 33 import std.typecons : Tuple, Nullable; 34 import std.algorithm : among; 35 36 alias Rval = Tuple!(Mutation.Kind[], "op", Mutation.Kind[], "expr"); 37 38 Nullable!Rval rval; 39 40 with (Mutation.Kind) { 41 if (op.among(OpKind.LT, OpKind.OO_Less)) { 42 rval = Rval([rorLE, rorpLE, rorNE, rorpNE], [rorFalse]); 43 } else if (op.among(OpKind.GT, OpKind.OO_Greater)) { 44 rval = Rval([rorGE, rorpGE, rorNE, rorpNE], [rorFalse]); 45 } else if (op.among(OpKind.LE, OpKind.OO_LessEqual)) { 46 rval = Rval([rorLT, rorpLT, rorEQ, rorpEQ], [rorTrue]); 47 } else if (op.among(OpKind.GE, OpKind.OO_GreaterEqual)) { 48 rval = Rval([rorGT, rorpGT, rorEQ, rorpEQ], [rorTrue]); 49 } else if (op.among(OpKind.EQ, OpKind.OO_EqualEqual)) { 50 rval = Rval([rorLE, rorpLE, rorGE, rorpGE], [rorFalse]); 51 } else if (op.among(OpKind.NE, OpKind.OO_ExclaimEqual)) { 52 rval = Rval([rorLT, rorpLT, rorGT, rorpGT], [rorTrue]); 53 } 54 } 55 56 // #SPC-plugin_mutate_mutation_ror_float 57 void floatingPointSchema() { 58 with (Mutation.Kind) { 59 if (op.among(OpKind.LT, OpKind.OO_Less)) { 60 rval.op = [rorGT, rorpGT]; 61 } else if (op.among(OpKind.GT, OpKind.OO_Greater)) { 62 rval.op = [rorLT, rorpLT]; 63 } else if (op.among(OpKind.LE, OpKind.OO_LessEqual)) { 64 rval.op = [rorGT, rorpGT]; 65 } else if (op.among(OpKind.GE, OpKind.OO_GreaterEqual)) { 66 rval.op = [rorLT, rorpLT]; 67 } 68 } 69 } 70 71 // #SPC-plugin_mutate_mutation_ror_enum 72 void enumSchema() { 73 with (Mutation.Kind) { 74 if (op.among(OpKind.EQ, OpKind.OO_EqualEqual)) { 75 if (tyi == OpTypeInfo.enumLhsIsMin) { 76 rval.op = [rorLE, rorpLE]; 77 } else if (tyi == OpTypeInfo.enumLhsIsMax) { 78 rval.op = [rorGE, rorpGE]; 79 } else if (tyi == OpTypeInfo.enumRhsIsMin) { 80 rval.op = [rorGE, rorpGE]; 81 } else if (tyi == OpTypeInfo.enumRhsIsMax) { 82 rval.op = [rorLE, rorpLE]; 83 } 84 } else if (op.among(OpKind.NE, OpKind.OO_ExclaimEqual)) { 85 if (tyi == OpTypeInfo.enumLhsIsMin) { 86 rval.op = [rorLT, rorpLT]; 87 } else if (tyi == OpTypeInfo.enumLhsIsMax) { 88 rval.op = [rorGT, rorpGT]; 89 } else if (tyi == OpTypeInfo.enumRhsIsMin) { 90 rval.op = [rorGT, rorpGT]; 91 } else if (tyi == OpTypeInfo.enumRhsIsMax) { 92 rval.op = [rorLT, rorpLT]; 93 } 94 } 95 } 96 } 97 98 // #SPC-plugin_mutate_mutation_ror_ptr 99 void pointerSchema() { 100 with (Mutation.Kind) { 101 if (op.among(OpKind.EQ, OpKind.OO_EqualEqual)) { 102 rval.op = [rorLE, rorGE, rorpNE]; 103 } else if (op.among(OpKind.NE, OpKind.OO_ExclaimEqual)) { 104 rval.op = [rorLT, rorGT, rorpEQ]; 105 } 106 } 107 } 108 109 // #SPC-plugin_mutate_mutation_ror_bool 110 void boolSchema() { 111 with (Mutation.Kind) { 112 if (op.among(OpKind.EQ, OpKind.OO_EqualEqual)) { 113 rval.op = [rorNE, rorpNE]; 114 } else if (op.among(OpKind.NE, OpKind.OO_ExclaimEqual)) { 115 rval.op = [rorEQ, rorpEQ]; 116 } 117 } 118 } 119 120 if (tyi == OpTypeInfo.floatingPoint) 121 floatingPointSchema(); 122 else if (tyi.among(OpTypeInfo.enumLhsIsMin, OpTypeInfo.enumLhsIsMax, 123 OpTypeInfo.enumRhsIsMin, OpTypeInfo.enumRhsIsMax)) 124 enumSchema(); 125 else if (tyi == OpTypeInfo.pointer) 126 pointerSchema(); 127 else if (tyi == OpTypeInfo.boolean) 128 boolSchema(); 129 130 return rval; 131 } 132 133 immutable bool[OpKind] isRor; 134 135 immutable Mutation.Kind[] rorMutationsAll; 136 immutable Mutation.Kind[] rorpMutationsAll; 137 138 shared static this() { 139 // dfmt off 140 with (OpKind) { 141 isRor = 142 [ 143 LT: true, // "<" 144 GT: true, // ">" 145 LE: true, // "<=" 146 GE: true, // ">=" 147 EQ: true, // "==" 148 NE: true, // "!=" 149 OO_Less: true, // "<" 150 OO_Greater: true, // ">" 151 OO_EqualEqual: true, // "==" 152 OO_ExclaimEqual: true, // "!=" 153 OO_LessEqual: true, // "<=" 154 OO_GreaterEqual: true, // ">=" 155 ]; 156 } 157 // dfmt on 158 159 with (Mutation.Kind) { 160 rorMutationsAll = [rorLT, rorLE, rorGT, rorGE, rorEQ, rorNE, rorTrue, rorFalse]; 161 rorpMutationsAll = [rorpLT, rorpLE, rorpGT, rorpGE, rorpEQ, rorpNE, rorTrue, rorFalse]; 162 } 163 }