src/compiler/source_inventory.panack
Green: covered; red: known zero; amber: unavailable. Blank lines are outside the executable-start-line denominator.
1 import "source_maps.panack" 2 3 // IDs are structural paths within a source snapshot, never emitted PCs. The 4 // exact snapshot/artifact/compiler envelope is part of every ID's identity. 5 record InventoryItem { 6 id: Str, 7 kind: Str, 8 detail: Str, 9 span: SourceSpan 10 } 11 12 pure inventory_item(id: Str, kind: Str, detail: Str, expression: Expr): [InventoryItem] { 13 match expression_span(expression) { 14 Some(span) => [InventoryItem(id, kind, detail, span)], 15 None() => [] 16 } 17 } 18 19 pure inventory_decision(id: Str, kind: Str, expression: Expr, outcomes: [Str]): [InventoryItem] { 20 mut items: [InventoryItem] = inventory_item(id, "decision", kind, expression) 21 for outcome in outcomes { 22 items = concat(items, inventory_item(id + "/" + outcome, "outcome", outcome, expression)) 23 } 24 items 25 } 26 27 pure inventory_expressions(values: [Expr], id: Str): [InventoryItem] { 28 mut items: [InventoryItem] = [] 29 mut index: Nat = 0 30 for value in values { 31 items = concat(items, inventory_expression(value, id + "/${index}")) 32 index = index + 1 33 } 34 items 35 } 36 37 pure inventory_expression(expression: Expr, id: Str): [InventoryItem] { 38 mut items: [InventoryItem] = inventory_item(id, "expression", "attempt", expression) 39 match unlocated_expression(expression) { 40 LocatedExpr(span, value) => {}, 41 NatExpr(value) => {}, DecimalExpr(value) => {}, StringExpr(value) => {}, 42 BoolExpr(value) => {}, NameExpr(value) => {}, FunctionExpr(value) => {}, 43 ArrayExpr(values) => { items = concat(items, inventory_expressions(values, id)); }, 44 UnaryExpr(operator, value) => { items = concat(items, inventory_expression(value, id + "/operand")); }, 45 BinaryExpr(operator, left, right) => { 46 if operator == "&&" || operator == "||" { 47 items = concat(items, inventory_decision(id + "/decision", operator, left, ["evaluate-right", "skip-right"])) 48 } 49 items = concat(items, inventory_expression(left, id + "/left")) 50 items = concat(items, inventory_expression(right, id + "/right")) 51 }, 52 CallExpr(name, arguments, types) => { items = concat(items, inventory_expressions(arguments, id + "/args")); }, 53 DotCallExpr(target, name, arguments, types) => { 54 items = concat(items, inventory_expression(target, id + "/receiver")) 55 items = concat(items, inventory_expressions(arguments, id + "/args")) 56 }, 57 FieldExpr(target, name) => { items = concat(items, inventory_expression(target, id + "/receiver")); }, 58 IndexExpr(target, index) => { 59 items = concat(items, inventory_expression(target, id + "/receiver")) 60 items = concat(items, inventory_expression(index, id + "/index")) 61 }, 62 IfExpr(condition, yes, no, has_else) => { 63 items = concat(items, inventory_decision(id + "/decision", "if", condition, ["true", "false"])) 64 items = concat(items, inventory_expression(condition, id + "/condition")) 65 items = concat(items, inventory_block(yes, id + "/true")) 66 items = concat(items, inventory_block(no, id + "/false")) 67 }, 68 BlockExpr(block) => { items = concat(items, inventory_block(block, id + "/block")); }, 69 MatchExpr(subject, arms) => { 70 items = concat(items, inventory_item(id + "/decision", "decision", "match", subject)) 71 items = concat(items, inventory_expression(subject, id + "/subject")) 72 mut index: Nat = 0 73 for arm in arms { 74 arm_id: Str = id + "/arm/${index}" 75 items = concat(items, inventory_item(arm_id, "outcome", arm.pattern.variant, arm.body)) 76 items = concat(items, inventory_expression(arm.body, arm_id + "/body")) 77 index = index + 1 78 } 79 } 80 } 81 items 82 } 83 84 // Statement anchors are their first evaluated expression, not the declaration 85 // name/type or punctuation. They have separate identities from that expression. 86 pure inventory_block(block: Block, id: Str): [InventoryItem] { 87 mut items: [InventoryItem] = [] 88 mut index: Nat = 0 89 for statement in block.statements { 90 key: Str = id + "/statement/${index}" 91 match statement { 92 BindingStatement(name, annotation, mutable, value) => { 93 items = concat(items, inventory_item(key, "statement", "binding", value)) 94 items = concat(items, inventory_expression(value, key + "/value")) 95 }, 96 AssignmentStatement(name, value) => { 97 items = concat(items, inventory_item(key, "statement", "assignment-or-inferred-binding", value)) 98 items = concat(items, inventory_expression(value, key + "/value")) 99 }, 100 ExpressionStatement(value) => { 101 items = concat(items, inventory_item(key, "statement", "expression", value)) 102 items = concat(items, inventory_expression(value, key + "/value")) 103 }, 104 WhileStatement(condition, body) => { 105 items = concat(items, inventory_item(key, "statement", "while", condition)) 106 items = concat(items, inventory_decision(key + "/decision", "while", condition, ["body", "exit"])) 107 items = concat(items, inventory_expression(condition, key + "/condition")) 108 items = concat(items, inventory_block(body, key + "/body")) 109 }, 110 ForStatement(name, values, body) => { 111 items = concat(items, inventory_item(key, "statement", "for", values)) 112 items = concat(items, inventory_decision(key + "/decision", "for", values, ["body", "exit"])) 113 items = concat(items, inventory_expression(values, key + "/iterable")) 114 items = concat(items, inventory_block(body, key + "/body")) 115 } 116 } 117 index = index + 1 118 } 119 match block.value { 120 NoBlockValue() => {}, 121 TailBlockValue(value) => { items = concat(items, inventory_expression(value, id + "/tail")); } 122 } 123 items 124 } 125 126 pure inventory_module(module: LoadedModule): [InventoryItem] { 127 mut items: [InventoryItem] = [] 128 mut index: Nat = 0 129 for declaration in module.parsed.program.declarations { 130 id: Str = "declaration/${index}" 131 span: SourceSpan = module.parsed.syntax[index].span 132 match declaration { 133 FunctionDeclaration(name, parameters, result, pure_effect, async_effect, body, types) => { 134 items = items.append(InventoryItem(id, "function", name, span)) 135 items = concat(items, inventory_block(body, id)) 136 }, 137 ImportDeclaration(path) => { items = items.append(InventoryItem(id, "excluded", "import", span)); }, 138 TypeDeclaration(name, base, guard) => { items = items.append(InventoryItem(id, "excluded", "compile-time-refinement", span)); }, 139 RecordDeclaration(name, types, fields) => { items = items.append(InventoryItem(id, "excluded", "record-declaration", span)); }, 140 EnumDeclaration(name, types, variants) => { items = items.append(InventoryItem(id, "excluded", "enum-declaration", span)); } 141 } 142 index = index + 1 143 } 144 items 145 } 146 147 // Foreign inventories are never decoded. The caller reproduces this envelope 148 // using explicit local roots and the installed compiler, then compares bytes. 149 pure serialize_source_inventory(project: LoadedProject, artifact: Bytes, compiler: Bytes, entry: Str, root: Str, stdlib: Str): Bytes { 150 snapshots: [SourceSnapshot] = source_snapshots(project, root, stdlib) 151 mut chunks: [Bytes] = [utf8_encode("PANACKINV1\nlocal-replay-v9\n"), source_map_blob(compiler), 152 encode_text(source_identifier(entry, root, stdlib)), source_map_blob(artifact), encode_u32(len(snapshots))] 153 mut size: Nat = 0 154 mut valid: Bool = byte_len(compiler) > 0 && byte_len(compiler) <= 16777216 && 155 byte_len(artifact) <= 16777216 && len(snapshots) <= 256 156 for chunk in chunks { size = size + byte_len(chunk); } 157 for snapshot in snapshots { 158 mut items: [InventoryItem] = [] 159 for module in project.modules { 160 if module.source_path == snapshot.path { items = inventory_module(module); } 161 } 162 chunks = chunks.append(encode_text(snapshot.name)).append(encode_text(snapshot.text)).append(encode_u32(len(items))) 163 size = size + 12 + byte_len(utf8_encode(snapshot.name)) + byte_len(utf8_encode(snapshot.text)) 164 valid = valid && len(items) <= 100000 165 for item in items { 166 if valid && size <= 16777216 { 167 chunk: Bytes = source_map_join([encode_text(item.id), encode_text(item.kind), encode_text(item.detail), 168 source_map_position(item.span.start), source_map_position(item.span.end)], 0, 5) 169 chunks = chunks.append(chunk) 170 size = size + byte_len(chunk) 171 } else { valid = false } 172 } 173 } 174 if valid && size <= 16777216 { source_map_join(chunks, 0, len(chunks)) } else { bytes() } 175 } 176 177 record InventoryArguments { 178 valid: Bool, 179 roots: [Str], 180 output: Str 181 } 182 183 pure inventory_arguments(values: [Str], checking: Bool): InventoryArguments { 184 mut roots: [Str] = [] 185 mut output: Str = "" 186 mut valid: Bool = len(values) >= 4 187 if valid { roots = roots.append(values[1]); } 188 mut index: Nat = 2 189 while index + 1 < len(values) { 190 flag: Str = values[index] 191 value: Str = values[index + 1] 192 if flag == (if checking { "--inventory" } else { "-o" }) && output == "" { 193 output = value 194 } else { 195 if flag == "--include" { roots = roots.append(value); } else { valid = false; } 196 } 197 index = index + 2 198 } 199 for root in roots { valid = valid && path_suffix(root) == ".panack"; } 200 InventoryArguments(valid && index == len(values) && output != "" && len(roots) <= 16, roots, output) 201 } 202 203 // Repeating roots deliberately creates distinct compilation contexts. Shared 204 // source identities must be deduplicated by a future suite aggregator, never by 205 // adding these counts. Sources are rechecked after *all* roots have been loaded. 206 run_inventory_command(values: [Str], checking: Bool): Nat { 207 args: InventoryArguments = inventory_arguments(values, checking) 208 if !args.valid { 209 eprint("error: inventory usage: inventory SOURCE.panack -o FILE [--include SOURCE.panack] | inventory-check SOURCE.panack --inventory FILE [--include SOURCE.panack]") 210 1 211 } else { 212 compiler_path: Str = environment_get("PANACKELTY_COMPILER_PATH") 213 match source_map_read(compiler_path, 16777216) { 214 Error(error) => { eprint("error: inventory compiler identity unavailable"); 1 }, 215 Ok(compiler) => { 216 // The running compiler was verified by the VM. This trusted identity 217 // input is compared exactly, not decoded again in the hosted compiler. 218 mut valid: Bool = byte_len(compiler) > 0 219 mut projects: [LoadedProject] = [] 220 mut paths: Set[Str] = set() 221 mut chunks: [Bytes] = [utf8_encode("PANACKINVENTORY1\n"), encode_u32(len(args.roots))] 222 mut size: Nat = byte_len(chunks[0]) + 4 223 root: Str = path_parent(path_resolve(args.roots[0])) 224 stdlib: Str = path_resolve(environment_get("PANACKELTY_STDLIB_PATH")) 225 output: Str = path_resolve(args.output) 226 if !checking && !source_map_destination_available(output) { valid = false; } 227 for source in args.roots { 228 entry: Str = path_resolve(source) 229 if paths.has(entry) { valid = false; } 230 paths = paths.add(entry) 231 if valid { 232 project: LoadedProject = load_project_for_inventory(entry) 233 projects = projects.append(project) 234 if len(project.diagnostics) > 0 { valid = false; } 235 else { 236 artifact: Bytes = serialize_bytecode(compile_program(project.program)) 237 inventory: Bytes = serialize_source_inventory(project, artifact, compiler, entry, root, stdlib) 238 size = size + 4 + byte_len(inventory) 239 valid = byte_len(inventory) > 0 && size <= 16777216 240 if valid { chunks = chunks.append(source_map_blob(inventory)); } 241 } 242 } 243 } 244 for project in projects { valid = valid && source_snapshots_unchanged(project); } 245 valid = valid && source_map_matches(compiler_path, compiler) 246 if !valid { eprint("error: inventory unavailable: invalid, changed, duplicate or excessive inputs, or existing output"); 1 } 247 else { 248 expected: Bytes = source_map_join(chunks, 0, len(chunks)) 249 if checking { 250 if source_map_matches(output, expected) { print("inventory: valid"); 0 } 251 else { eprint("error: inventory unavailable: missing, malformed, stale or incompatible inventory"); 1 } 252 } else { 253 if source_map_destination_available(output) && source_map_write(output, expected) && source_map_matches(output, expected) { 254 print("wrote inventory " + args.output) 255 0 256 } else { eprint("error: could not write inventory; discard any partial output"); 1 } 257 } 258 } 259 } 260 } 261 } 262 } 263
Functions
[
{
"id": "declaration/2",
"name": "inventory_item",
"line": 12,
"state": "covered",
"entries": "1847"
},
{
"id": "declaration/3",
"name": "inventory_decision",
"line": 19,
"state": "covered",
"entries": "111"
},
{
"id": "declaration/4",
"name": "inventory_expressions",
"line": 27,
"state": "covered",
"entries": "269"
},
{
"id": "declaration/5",
"name": "inventory_expression",
"line": 37,
"state": "covered",
"entries": "1212"
},
{
"id": "declaration/6",
"name": "inventory_block",
"line": 86,
"state": "covered",
"entries": "204"
},
{
"id": "declaration/7",
"name": "inventory_module",
"line": 126,
"state": "covered",
"entries": "25"
},
{
"id": "declaration/8",
"name": "serialize_source_inventory",
"line": 149,
"state": "covered",
"entries": "5"
},
{
"id": "declaration/10",
"name": "inventory_arguments",
"line": 183,
"state": "covered",
"entries": "5"
},
{
"id": "declaration/11",
"name": "run_inventory_command",
"line": 206,
"state": "zero",
"entries": "0"
}
]Source branch outcomes
[
{
"id": "declaration/2/tail/arm/0",
"outcome": "Some",
"line": 14,
"state": "covered",
"hits": "1847"
},
{
"id": "declaration/2/tail/arm/1",
"outcome": "None",
"line": 15,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/3/statement/1/decision/body",
"outcome": "body",
"line": 21,
"state": "covered",
"hits": "222"
},
{
"id": "declaration/3/statement/1/decision/exit",
"outcome": "exit",
"line": 21,
"state": "covered",
"hits": "111"
},
{
"id": "declaration/4/statement/2/decision/body",
"outcome": "body",
"line": 30,
"state": "covered",
"hits": "228"
},
{
"id": "declaration/4/statement/2/decision/exit",
"outcome": "exit",
"line": 30,
"state": "covered",
"hits": "269"
},
{
"id": "declaration/5/statement/1/value/arm/0",
"outcome": "LocatedExpr",
"line": 40,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/5/statement/1/value/arm/1",
"outcome": "NatExpr",
"line": 41,
"state": "covered",
"hits": "165"
},
{
"id": "declaration/5/statement/1/value/arm/2",
"outcome": "DecimalExpr",
"line": 41,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/5/statement/1/value/arm/3",
"outcome": "StringExpr",
"line": 41,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/5/statement/1/value/arm/4",
"outcome": "BoolExpr",
"line": 42,
"state": "covered",
"hits": "47"
},
{
"id": "declaration/5/statement/1/value/arm/5",
"outcome": "NameExpr",
"line": 42,
"state": "covered",
"hits": "455"
},
{
"id": "declaration/5/statement/1/value/arm/6",
"outcome": "FunctionExpr",
"line": 42,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/5/statement/1/value/arm/7",
"outcome": "ArrayExpr",
"line": 43,
"state": "covered",
"hits": "29"
},
{
"id": "declaration/5/statement/1/value/arm/8",
"outcome": "UnaryExpr",
"line": 44,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/5/statement/1/value/arm/9",
"outcome": "BinaryExpr",
"line": 45,
"state": "covered",
"hits": "144"
},
{
"id": "declaration/5/statement/1/value/arm/9/body/block/statement/0/value/decision/true",
"outcome": "true",
"line": 46,
"state": "covered",
"hits": "23"
},
{
"id": "declaration/5/statement/1/value/arm/9/body/block/statement/0/value/decision/false",
"outcome": "false",
"line": 46,
"state": "covered",
"hits": "121"
},
{
"id": "declaration/5/statement/1/value/arm/9/body/block/statement/0/value/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 46,
"state": "covered",
"hits": "129"
},
{
"id": "declaration/5/statement/1/value/arm/9/body/block/statement/0/value/condition/decision/skip-right",
"outcome": "skip-right",
"line": 46,
"state": "covered",
"hits": "15"
},
{
"id": "declaration/5/statement/1/value/arm/10",
"outcome": "CallExpr",
"line": 52,
"state": "covered",
"hits": "128"
},
{
"id": "declaration/5/statement/1/value/arm/11",
"outcome": "DotCallExpr",
"line": 53,
"state": "covered",
"hits": "112"
},
{
"id": "declaration/5/statement/1/value/arm/12",
"outcome": "FieldExpr",
"line": 57,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/5/statement/1/value/arm/13",
"outcome": "IndexExpr",
"line": 58,
"state": "covered",
"hits": "63"
},
{
"id": "declaration/5/statement/1/value/arm/14",
"outcome": "IfExpr",
"line": 62,
"state": "covered",
"hits": "37"
},
{
"id": "declaration/5/statement/1/value/arm/15",
"outcome": "BlockExpr",
"line": 68,
"state": "covered",
"hits": "16"
},
{
"id": "declaration/5/statement/1/value/arm/16",
"outcome": "MatchExpr",
"line": 69,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/5/statement/1/value/arm/16/body/block/statement/3/decision/body",
"outcome": "body",
"line": 73,
"state": "covered",
"hits": "16"
},
{
"id": "declaration/5/statement/1/value/arm/16/body/block/statement/3/decision/exit",
"outcome": "exit",
"line": 73,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/6/statement/2/decision/body",
"outcome": "body",
"line": 89,
"state": "covered",
"hits": "278"
},
{
"id": "declaration/6/statement/2/decision/exit",
"outcome": "exit",
"line": 89,
"state": "covered",
"hits": "204"
},
{
"id": "declaration/6/statement/2/body/statement/1/value/arm/0",
"outcome": "BindingStatement",
"line": 92,
"state": "covered",
"hits": "66"
},
{
"id": "declaration/6/statement/2/body/statement/1/value/arm/1",
"outcome": "AssignmentStatement",
"line": 96,
"state": "covered",
"hits": "120"
},
{
"id": "declaration/6/statement/2/body/statement/1/value/arm/2",
"outcome": "ExpressionStatement",
"line": 100,
"state": "covered",
"hits": "41"
},
{
"id": "declaration/6/statement/2/body/statement/1/value/arm/3",
"outcome": "WhileStatement",
"line": 104,
"state": "covered",
"hits": "29"
},
{
"id": "declaration/6/statement/2/body/statement/1/value/arm/4",
"outcome": "ForStatement",
"line": 110,
"state": "covered",
"hits": "22"
},
{
"id": "declaration/6/statement/3/value/arm/0",
"outcome": "NoBlockValue",
"line": 120,
"state": "covered",
"hits": "85"
},
{
"id": "declaration/6/statement/3/value/arm/1",
"outcome": "TailBlockValue",
"line": 121,
"state": "covered",
"hits": "119"
},
{
"id": "declaration/7/statement/2/decision/body",
"outcome": "body",
"line": 129,
"state": "covered",
"hits": "109"
},
{
"id": "declaration/7/statement/2/decision/exit",
"outcome": "exit",
"line": 129,
"state": "covered",
"hits": "25"
},
{
"id": "declaration/7/statement/2/body/statement/2/value/arm/0",
"outcome": "FunctionDeclaration",
"line": 133,
"state": "covered",
"hits": "63"
},
{
"id": "declaration/7/statement/2/body/statement/2/value/arm/1",
"outcome": "ImportDeclaration",
"line": 137,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/7/statement/2/body/statement/2/value/arm/2",
"outcome": "TypeDeclaration",
"line": 138,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/7/statement/2/body/statement/2/value/arm/3",
"outcome": "RecordDeclaration",
"line": 139,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/7/statement/2/body/statement/2/value/arm/4",
"outcome": "EnumDeclaration",
"line": 140,
"state": "covered",
"hits": "22"
},
{
"id": "declaration/8/statement/3/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 154,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/8/statement/3/value/decision/skip-right",
"outcome": "skip-right",
"line": 154,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/8/statement/3/value/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 154,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/8/statement/3/value/left/decision/skip-right",
"outcome": "skip-right",
"line": 154,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/8/statement/3/value/left/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 154,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/8/statement/3/value/left/left/decision/skip-right",
"outcome": "skip-right",
"line": 154,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/8/statement/4/decision/body",
"outcome": "body",
"line": 156,
"state": "covered",
"hits": "25"
},
{
"id": "declaration/8/statement/4/decision/exit",
"outcome": "exit",
"line": 156,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/8/statement/5/decision/body",
"outcome": "body",
"line": 157,
"state": "covered",
"hits": "15"
},
{
"id": "declaration/8/statement/5/decision/exit",
"outcome": "exit",
"line": 157,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/8/statement/5/body/statement/1/decision/body",
"outcome": "body",
"line": 159,
"state": "covered",
"hits": "45"
},
{
"id": "declaration/8/statement/5/body/statement/1/decision/exit",
"outcome": "exit",
"line": 159,
"state": "covered",
"hits": "15"
},
{
"id": "declaration/8/statement/5/body/statement/1/body/tail/decision/true",
"outcome": "true",
"line": 160,
"state": "covered",
"hits": "15"
},
{
"id": "declaration/8/statement/5/body/statement/1/body/tail/decision/false",
"outcome": "false",
"line": 160,
"state": "covered",
"hits": "30"
},
{
"id": "declaration/8/statement/5/body/statement/4/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 164,
"state": "covered",
"hits": "12"
},
{
"id": "declaration/8/statement/5/body/statement/4/value/decision/skip-right",
"outcome": "skip-right",
"line": 164,
"state": "covered",
"hits": "3"
},
{
"id": "declaration/8/statement/5/body/statement/5/decision/body",
"outcome": "body",
"line": 165,
"state": "covered",
"hits": "1335"
},
{
"id": "declaration/8/statement/5/body/statement/5/decision/exit",
"outcome": "exit",
"line": 165,
"state": "covered",
"hits": "15"
},
{
"id": "declaration/8/statement/5/body/statement/5/body/tail/decision/true",
"outcome": "true",
"line": 166,
"state": "covered",
"hits": "1068"
},
{
"id": "declaration/8/statement/5/body/statement/5/body/tail/decision/false",
"outcome": "false",
"line": 166,
"state": "covered",
"hits": "267"
},
{
"id": "declaration/8/statement/5/body/statement/5/body/tail/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 166,
"state": "covered",
"hits": "1068"
},
{
"id": "declaration/8/statement/5/body/statement/5/body/tail/condition/decision/skip-right",
"outcome": "skip-right",
"line": 166,
"state": "covered",
"hits": "267"
},
{
"id": "declaration/8/tail/decision/true",
"outcome": "true",
"line": 174,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/8/tail/decision/false",
"outcome": "false",
"line": 174,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/8/tail/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 174,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/8/tail/condition/decision/skip-right",
"outcome": "skip-right",
"line": 174,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/10/statement/3/value/decision/true",
"outcome": "true",
"line": 187,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/10/statement/3/value/decision/false",
"outcome": "false",
"line": 187,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/10/statement/5/decision/body",
"outcome": "body",
"line": 189,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/statement/5/decision/exit",
"outcome": "exit",
"line": 189,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/decision/true",
"outcome": "true",
"line": 192,
"state": "covered",
"hits": "3"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/decision/false",
"outcome": "false",
"line": 192,
"state": "covered",
"hits": "2"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 192,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/condition/decision/skip-right",
"outcome": "skip-right",
"line": 192,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/condition/left/right/decision/true",
"outcome": "true",
"line": 192,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/condition/left/right/decision/false",
"outcome": "false",
"line": 192,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/false/tail/decision/true",
"outcome": "true",
"line": 195,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/10/statement/5/body/statement/2/value/false/tail/decision/false",
"outcome": "false",
"line": 195,
"state": "covered",
"hits": "2"
},
{
"id": "declaration/10/statement/6/decision/body",
"outcome": "body",
"line": 199,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/10/statement/6/decision/exit",
"outcome": "exit",
"line": 199,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/statement/6/body/statement/0/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 199,
"state": "covered",
"hits": "2"
},
{
"id": "declaration/10/statement/6/body/statement/0/value/decision/skip-right",
"outcome": "skip-right",
"line": 199,
"state": "covered",
"hits": "2"
},
{
"id": "declaration/10/tail/args/0/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 200,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/10/tail/args/0/decision/skip-right",
"outcome": "skip-right",
"line": 200,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/tail/args/0/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 200,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/10/tail/args/0/left/decision/skip-right",
"outcome": "skip-right",
"line": 200,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/10/tail/args/0/left/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 200,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/10/tail/args/0/left/left/decision/skip-right",
"outcome": "skip-right",
"line": 200,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/11/tail/decision/true",
"outcome": "true",
"line": 208,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/decision/false",
"outcome": "false",
"line": 208,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/0",
"outcome": "Error",
"line": 214,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1",
"outcome": "Ok",
"line": 215,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/8/value/decision/true",
"outcome": "true",
"line": 226,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/8/value/decision/false",
"outcome": "false",
"line": 226,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/8/value/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 226,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/8/value/condition/decision/skip-right",
"outcome": "skip-right",
"line": 226,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/decision/body",
"outcome": "body",
"line": 227,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/decision/exit",
"outcome": "exit",
"line": 227,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/statement/1/value/decision/true",
"outcome": "true",
"line": 229,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/statement/1/value/decision/false",
"outcome": "false",
"line": 229,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/decision/true",
"outcome": "true",
"line": 231,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/decision/false",
"outcome": "false",
"line": 231,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/decision/true",
"outcome": "true",
"line": 234,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/decision/false",
"outcome": "false",
"line": 234,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/false/statement/3/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 239,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/false/statement/3/value/decision/skip-right",
"outcome": "skip-right",
"line": 239,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/false/tail/decision/true",
"outcome": "true",
"line": 240,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/9/body/tail/true/tail/false/tail/decision/false",
"outcome": "false",
"line": 240,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/10/decision/body",
"outcome": "body",
"line": 244,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/10/decision/exit",
"outcome": "exit",
"line": 244,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/10/body/statement/0/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 244,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/10/body/statement/0/value/decision/skip-right",
"outcome": "skip-right",
"line": 244,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/11/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 245,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/statement/11/value/decision/skip-right",
"outcome": "skip-right",
"line": 245,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/decision/true",
"outcome": "true",
"line": 246,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/decision/false",
"outcome": "false",
"line": 246,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/decision/true",
"outcome": "true",
"line": 249,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/decision/false",
"outcome": "false",
"line": 249,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/true/tail/decision/true",
"outcome": "true",
"line": 250,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/true/tail/decision/false",
"outcome": "false",
"line": 250,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/decision/true",
"outcome": "true",
"line": 253,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/decision/false",
"outcome": "false",
"line": 253,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 253,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/condition/decision/skip-right",
"outcome": "skip-right",
"line": 253,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/condition/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 253,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/false/tail/arm/1/body/block/tail/false/tail/false/tail/condition/left/decision/skip-right",
"outcome": "skip-right",
"line": 253,
"state": "zero",
"hits": "0"
}
]Reviewed declaration exclusions
[
{
"id": "declaration/0",
"reason": "import",
"line": 1
},
{
"id": "declaration/1",
"reason": "record-declaration",
"line": 5
},
{
"id": "declaration/9",
"reason": "record-declaration",
"line": 177
}
]