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.database.type; 11 12 import core.time : Duration; 13 import std.datetime : SysTime; 14 15 import sumtype; 16 17 import dextool.type : AbsolutePath, Path; 18 import dextool.plugin.mutate.backend.type; 19 20 import dextool.plugin.mutate.backend.database.schema : MarkedMutantTbl; 21 public import dextool.plugin.mutate.backend.database.schema : MutantTimeoutCtxTbl; 22 23 alias MutantTimeoutCtx = MutantTimeoutCtxTbl; 24 25 @safe: 26 27 /// Primary key in the mutation table 28 struct MutationId { 29 long value; 30 alias value this; 31 } 32 33 /// Primary key for mutation status 34 struct MutationStatusId { 35 long value; 36 alias value this; 37 } 38 39 /// Primary key in the files table 40 struct FileId { 41 long value; 42 alias value this; 43 } 44 45 /// Primary key in the test_case table 46 struct TestCaseId { 47 long value; 48 alias value this; 49 } 50 51 /// Primary key for mutation schematas. 52 struct SchemataId { 53 long value; 54 alias value this; 55 } 56 57 /// Primary key for a schemata fragment. 58 struct SchemataFragmentId { 59 long value; 60 alias value this; 61 } 62 63 struct MutationEntry { 64 MutationId id; 65 Path file; 66 SourceLoc sloc; 67 MutationPoint mp; 68 Duration timeSpentMutating; 69 Language lang; 70 } 71 72 struct NextMutationEntry { 73 import std.typecons : Nullable; 74 75 enum Status { 76 /// Mutant retrieved. 77 ok, 78 /// All mutants tested. 79 done, 80 } 81 82 Status st; 83 Nullable!MutationEntry entry; 84 } 85 86 struct MutationPointEntry { 87 MutationPoint mp; 88 Path file; 89 /// Start of the mutation point. 90 SourceLoc sloc; 91 /// End of the mutation point. 92 SourceLoc slocEnd; 93 } 94 95 /// The source code mutations for a mutation point. 96 struct MutationPointEntry2 { 97 Path file; 98 Offset offset; 99 /// Start of the mutation point. 100 SourceLoc sloc; 101 /// End of the mutation point. 102 SourceLoc slocEnd; 103 CodeMutant[] cms; 104 105 void put(CodeMutant m) @safe pure nothrow { 106 cms ~= m; 107 } 108 } 109 110 /// Report about mutants of a specific kind(s). 111 struct MutationReportEntry { 112 /// 113 long count; 114 /// Test time spent on the mutants. 115 Duration time; 116 } 117 118 /// Mutants that are tagged with nomut of a specific kind(s). 119 struct MetadataNoMutEntry { 120 /// 121 long count; 122 } 123 124 struct MutantInfo { 125 MutationId id; 126 Mutation.Status status; 127 Mutation.Kind kind; 128 SourceLoc sloc; 129 } 130 131 struct TestCaseInfo { 132 /// The sum on the execution time of killing the mutants. 133 Duration time; 134 /// 135 long killedMutants; 136 } 137 138 /// What mutants a test case killed. 139 struct TestCaseInfo2 { 140 TestCase name; 141 MutationId[] killed; 142 } 143 144 struct MutationStatusTime { 145 import std.datetime : SysTime; 146 147 MutationStatusId id; 148 SysTime updated; 149 } 150 151 struct MutationStatus { 152 import std.datetime : SysTime; 153 import std.typecons : Nullable; 154 155 MutationStatusId statusId; 156 Mutation.Status status; 157 MutantTestCount testCnt; 158 SysTime updated; 159 Nullable!SysTime added; 160 } 161 162 /// Metadata about a line in a file. 163 struct LineMetadata { 164 FileId id; 165 uint line; 166 LineAttr attr; 167 168 this(FileId fid, uint line) { 169 this(fid, line, LineAttr.init); 170 } 171 172 this(FileId fid, uint line, LineAttr attr) { 173 this.id = fid; 174 this.line = line; 175 this.attr = attr; 176 } 177 178 void set(NoMut a) @trusted pure nothrow @nogc { 179 attr = LineAttr(a); 180 } 181 182 bool isNoMut() @safe pure nothrow const @nogc { 183 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 184 } 185 } 186 187 struct NoMetadata { 188 } 189 190 /// A mutation suppression with optional tag and comment. 191 struct NoMut { 192 string tag; 193 string comment; 194 } 195 196 /// Metadata attributes that may be attached to a mutant. 197 alias MutantAttr = SumType!(NoMetadata, NoMut); 198 199 /// Metadata attributes that may be attached to a line. 200 alias LineAttr = SumType!(NoMetadata, NoMut); 201 202 /// Metadata about a mutant. 203 struct MutantMetaData { 204 import std.range : isOutputRange; 205 206 MutationId id; 207 MutantAttr attr; 208 209 this(MutationId id) { 210 this(id, MutantAttr.init); 211 } 212 213 this(MutationId id, MutantAttr attr) { 214 this.id = id; 215 this.attr = attr; 216 } 217 218 void set(NoMut a) @trusted pure nothrow @nogc { 219 attr = MutantAttr(a); 220 } 221 222 bool isNoMut() @safe pure nothrow const @nogc { 223 return attr.match!((NoMetadata a) => false, (NoMut a) => true); 224 } 225 226 string kindToString() @safe pure const { 227 import std.array : appender; 228 import std.format : FormatSpec; 229 230 auto buf = appender!string; 231 kindToString(buf); 232 return buf.data; 233 } 234 235 void kindToString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 236 import std.range : put; 237 238 attr.match!((NoMetadata a) {}, (NoMut a) => put(w, "nomut")); 239 } 240 241 import std.range : isOutputRange; 242 243 string toString() @safe pure const { 244 import std.array : appender; 245 246 auto buf = appender!string; 247 toString(buf); 248 return buf.data; 249 } 250 251 void toString(Writer)(ref Writer w) const if (isOutputRange!(Writer, char)) { 252 kindToString(w); 253 } 254 } 255 256 struct Rationale { 257 string payload; 258 alias payload this; 259 } 260 261 struct MarkedMutant { 262 MutationStatusId statusId; 263 /// Checksum of the marked mutant. 264 Checksum statusChecksum; 265 266 MutationId mutationId; 267 268 SourceLoc sloc; 269 Path path; 270 271 /// The status it should always be changed to. 272 Mutation.Status toStatus; 273 274 /// Time when the mutant where marked. 275 SysTime time; 276 277 Rationale rationale; 278 279 string mutText; 280 } 281 282 /// A fragment of a schemata which is one application. 283 struct SchemataFragment { 284 Path file; 285 Offset offset; 286 const(ubyte)[] text; 287 } 288 289 struct Schemata { 290 SchemataId id; 291 292 /// Sorted in the order they should be applied. 293 SchemataFragment[] fragments; 294 }