src/compiler/source_maps.panack
Green: covered; red: known zero; amber: unavailable. Blank lines are outside the executable-start-line denominator.
1 import "loader.panack" 2 import "diagnostics.panack" 3 4 record SourceSnapshot { 5 name: Str, 6 path: Str, 7 text: Str 8 } 9 10 pure source_snapshot_less(left: SourceSnapshot, right: SourceSnapshot): Bool { 11 left.name < right.name 12 } 13 14 pure source_path_parts(path: Str): [Str] { 15 mut parts: [Str] = [] 16 mut start: Nat = 0 17 mut cursor: Nat = 0 18 while cursor <= len(path) { 19 if cursor == len(path) || path[cursor] == "/" { 20 if start < cursor { parts = append(parts, slice(path, start, cursor)); } 21 start = cursor + 1 22 } 23 cursor = cursor + 1 24 } 25 parts 26 } 27 28 // Inputs are normalized absolute paths from the loader. Parent segments are 29 // descriptive identifiers only: the consumer never opens paths from a sidecar. 30 pure source_relative_path(root: Str, path: Str): Str { 31 base: [Str] = source_path_parts(root) 32 target: [Str] = source_path_parts(path) 33 mut common: Nat = 0 34 while common < len(base) && common < len(target) && base[common] == target[common] { 35 common = common + 1 36 } 37 mut output: Str = "" 38 for index in common..len(base) { output = output + "../"; } 39 for index in common..len(target) { 40 output = output + target[index] 41 if index + 1 < len(target) { output = output + "/"; } 42 } 43 output 44 } 45 46 pure source_identifier(path: Str, root: Str, stdlib_root: Str): Str { 47 if starts_with(path, stdlib_root + "/") { 48 "stdlib/" + source_relative_path(stdlib_root, path) 49 } else { 50 "project/" + source_relative_path(root, path) 51 } 52 } 53 54 pure source_snapshots(project: LoadedProject, root: Str, stdlib_root: Str): [SourceSnapshot] { 55 mut snapshots: [SourceSnapshot] = [] 56 for path in project.source_paths { 57 snapshots = append(snapshots, SourceSnapshot(source_identifier(path, root, stdlib_root), path, project.sources.get(path))) 58 } 59 snapshots.sort_by(@source_snapshot_less) 60 } 61 62 pure source_map_blob(data: Bytes): Bytes { 63 bytes_concat(encode_u32(byte_len(data)), data) 64 } 65 66 pure source_map_position(position: SourcePos): Bytes { 67 bytes_concat(bytes_concat(encode_u32(position.offset), encode_u32(position.line)), encode_u32(position.column)) 68 } 69 70 // Join a bounded set of chunks as a balanced tree. In particular, do not copy 71 // the entire captured source closure for each emitted instruction. 72 pure source_map_join(chunks: [Bytes], start: Nat, end: Nat): Bytes { 73 if start >= end { bytes() } 74 else { 75 if end == start + 1 { chunks[start] } 76 else { 77 middle: Nat = quotient(start + end, 2) 78 bytes_concat(source_map_join(chunks, start, middle), source_map_join(chunks, middle, end)) 79 } 80 } 81 } 82 83 // No consumer decodes foreign bytes. Reproduction by the installed compiler is 84 // the trust boundary; this marker specifies a format, not producer authentication. 85 // The format embeds exact artifact/source bytes rather than collision-prone IDs. 86 pure serialize_source_map(project: LoadedProject, mapped: SourceMappedProgram, artifact: Bytes, entry: Str, root: Str, stdlib_root: Str): Bytes { 87 snapshots: [SourceSnapshot] = source_snapshots(project, root, stdlib_root) 88 mut valid: Bool = byte_len(artifact) <= 16777216 && len(snapshots) <= 256 89 mut chunks: [Bytes] = [utf8_encode("PANACKMAP1\nlocal-replay-v9\n"), 90 encode_text(source_identifier(entry, root, stdlib_root)), source_map_blob(artifact), encode_u32(len(snapshots))] 91 mut size: Nat = 0 92 for chunk in chunks { size = size + byte_len(chunk); } 93 valid = valid && size <= 16777216 94 mut indices: Map[Str,Nat] = map() 95 mut index: Nat = 0 96 for snapshot in snapshots { 97 if valid { 98 indices = indices.put(snapshot.path, index) 99 name: Bytes = encode_text(snapshot.name) 100 text: Bytes = encode_text(snapshot.text) 101 size = size + byte_len(name) + byte_len(text) 102 valid = size <= 16777216 103 if valid { chunks = chunks.append(name).append(text); } 104 index = index + 1 105 } 106 } 107 chunks = chunks.append(encode_u32(len(mapped.sources))) 108 size = size + 4 109 for function in mapped.sources { 110 if valid { 111 header: Bytes = bytes_concat(encode_text(function.name), encode_u32(len(function.entries))) 112 size = size + byte_len(header) 113 valid = size <= 16777216 114 if valid { chunks = chunks.append(header); } 115 for location in function.entries { 116 span: SourceSpan = location.span 117 size = size + 33 118 if valid && size <= 16777216 && indices.has(span.start.file) && span.start.file == span.end.file { 119 mut chunk: Bytes = bytes_concat(encode_u32(location.index), encode_u32(indices.get(span.start.file))) 120 chunk = bytes_concat(chunk, source_map_position(span.start)) 121 chunk = bytes_concat(chunk, source_map_position(span.end)) 122 chunk = byte_append(chunk, if location.lowered { 1 } else { 0 }) 123 chunks = chunks.append(chunk) 124 } else { valid = false } 125 } 126 } 127 } 128 if valid && size <= 16777216 { source_map_join(chunks, 0, len(chunks)) } else { bytes() } 129 } 130 131 source_map_read(path: Str, limit: Nat): Result[Bytes,Str] { 132 match path_from_text(path) { 133 Error(error) => Error("invalid path"), 134 Ok(file) => match fs_read(file, limit) { 135 Error(error) => Error("file unavailable or exceeds source-map limit"), 136 Ok(data) => Ok(data) 137 } 138 } 139 } 140 141 source_map_matches(path: Str, expected: Bytes): Bool { 142 match source_map_read(path, byte_len(expected)) { 143 Error(error) => false, 144 Ok(actual) => actual == expected 145 } 146 } 147 148 // Detect observed modifications since loading. This is not an atomic snapshot 149 // of a concurrently edited tree; all reported coordinates describe captured text. 150 source_snapshots_unchanged(project: LoadedProject): Bool { 151 mut unchanged: Bool = true 152 for path in project.source_paths { 153 if !source_map_matches(path, utf8_encode(project.sources.get(path))) { unchanged = false; } 154 } 155 unchanged 156 } 157 158 pure source_map_escape(text: Str): Str { 159 mut output: Str = "" 160 for index in 0..len(text) { output = output + diagnostic_character(text[index]); } 161 output 162 } 163 164 pure source_map_location(project: LoadedProject, mapped: SourceMappedProgram, function_name: Str, pc: Nat, root: Str, stdlib_root: Str): Str { 165 mut output: Str = "source-map: unavailable" 166 for function in mapped.sources { 167 if function.name == function_name { 168 for location in function.entries { 169 if location.index == pc { 170 span: SourceSpan = location.span 171 kind: Str = if location.lowered { "lowered" } else { "expression" } 172 file: Str = source_map_escape(source_identifier(span.start.file, root, stdlib_root)) 173 name: Str = source_map_escape(function_name) 174 start: Nat = span.start.offset 175 end: Nat = span.end.offset 176 line: Nat = span.start.line 177 column: Nat = span.start.column 178 end_line: Nat = span.end.line 179 end_column: Nat = span.end.column 180 source: Str = project.sources.get(span.start.file) 181 expression: Str = source_map_escape(slice(source, start, end)) 182 output = "source-map: ${kind}\nfunction: ${name}\ninstruction: ${pc}\nfile: ${file}\nrange: ${start}..${end}\nstart: ${line}:${column}\nend: ${end_line}:${end_column}\nexpression: ${expression}" 183 } 184 } 185 } 186 } 187 output 188 } 189 190 // Fresh destinations prevent overwriting loaded sources through existing hard 191 // links or symlinks as well as ordinary path aliases. Publication is not atomic; 192 // consumers reject incomplete pairs. Output directories must be caller-controlled. 193 source_map_destination_available(path: Str): Bool { 194 match path_from_text(path) { 195 Error(error) => false, 196 Ok(file) => match fs_metadata(file) { 197 Ok(metadata) => false, 198 Error(error) => error.code == "not_found" 199 } 200 } 201 } 202 203 source_map_write(path: Str, data: Bytes): Bool { 204 match path_from_text(path) { 205 Error(error) => false, 206 Ok(file) => match fs_write(file, data) { 207 Error(error) => false, 208 Ok(unit) => true 209 } 210 } 211 } 212
Functions
[
{
"id": "declaration/3",
"name": "source_snapshot_less",
"line": 10,
"state": "covered",
"entries": "132"
},
{
"id": "declaration/4",
"name": "source_path_parts",
"line": 14,
"state": "covered",
"entries": "186"
},
{
"id": "declaration/5",
"name": "source_relative_path",
"line": 30,
"state": "covered",
"entries": "93"
},
{
"id": "declaration/6",
"name": "source_identifier",
"line": 46,
"state": "covered",
"entries": "91"
},
{
"id": "declaration/7",
"name": "source_snapshots",
"line": 54,
"state": "covered",
"entries": "18"
},
{
"id": "declaration/8",
"name": "source_map_blob",
"line": 62,
"state": "covered",
"entries": "70"
},
{
"id": "declaration/9",
"name": "source_map_position",
"line": 66,
"state": "covered",
"entries": "3572"
},
{
"id": "declaration/10",
"name": "source_map_join",
"line": 72,
"state": "covered",
"entries": "14015"
},
{
"id": "declaration/11",
"name": "serialize_source_map",
"line": 86,
"state": "covered",
"entries": "8"
},
{
"id": "declaration/12",
"name": "source_map_read",
"line": 131,
"state": "covered",
"entries": "19"
},
{
"id": "declaration/13",
"name": "source_map_matches",
"line": 141,
"state": "covered",
"entries": "19"
},
{
"id": "declaration/14",
"name": "source_snapshots_unchanged",
"line": 150,
"state": "covered",
"entries": "4"
},
{
"id": "declaration/15",
"name": "source_map_escape",
"line": 158,
"state": "covered",
"entries": "319"
},
{
"id": "declaration/16",
"name": "source_map_location",
"line": 164,
"state": "covered",
"entries": "9"
},
{
"id": "declaration/17",
"name": "source_map_destination_available",
"line": 193,
"state": "zero",
"entries": "0"
},
{
"id": "declaration/18",
"name": "source_map_write",
"line": 203,
"state": "zero",
"entries": "0"
}
]Source branch outcomes
[
{
"id": "declaration/4/statement/3/decision/body",
"outcome": "body",
"line": 18,
"state": "covered",
"hits": "13282"
},
{
"id": "declaration/4/statement/3/decision/exit",
"outcome": "exit",
"line": 18,
"state": "covered",
"hits": "186"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/decision/true",
"outcome": "true",
"line": 19,
"state": "covered",
"hits": "1701"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/decision/false",
"outcome": "false",
"line": 19,
"state": "covered",
"hits": "11581"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 19,
"state": "covered",
"hits": "13096"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/condition/decision/skip-right",
"outcome": "skip-right",
"line": 19,
"state": "covered",
"hits": "186"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/true/statement/0/value/decision/true",
"outcome": "true",
"line": 20,
"state": "covered",
"hits": "1514"
},
{
"id": "declaration/4/statement/3/body/statement/0/value/true/statement/0/value/decision/false",
"outcome": "false",
"line": 20,
"state": "covered",
"hits": "187"
},
{
"id": "declaration/5/statement/3/decision/body",
"outcome": "body",
"line": 34,
"state": "covered",
"hits": "709"
},
{
"id": "declaration/5/statement/3/decision/exit",
"outcome": "exit",
"line": 34,
"state": "covered",
"hits": "93"
},
{
"id": "declaration/5/statement/3/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 34,
"state": "covered",
"hits": "710"
},
{
"id": "declaration/5/statement/3/condition/decision/skip-right",
"outcome": "skip-right",
"line": 34,
"state": "covered",
"hits": "92"
},
{
"id": "declaration/5/statement/3/condition/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 34,
"state": "covered",
"hits": "710"
},
{
"id": "declaration/5/statement/3/condition/left/decision/skip-right",
"outcome": "skip-right",
"line": 34,
"state": "covered",
"hits": "92"
},
{
"id": "declaration/5/statement/5/decision/body",
"outcome": "body",
"line": 38,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/5/statement/5/decision/exit",
"outcome": "exit",
"line": 38,
"state": "covered",
"hits": "93"
},
{
"id": "declaration/5/statement/6/decision/body",
"outcome": "body",
"line": 39,
"state": "covered",
"hits": "95"
},
{
"id": "declaration/5/statement/6/decision/exit",
"outcome": "exit",
"line": 39,
"state": "covered",
"hits": "93"
},
{
"id": "declaration/5/statement/6/body/tail/decision/true",
"outcome": "true",
"line": 41,
"state": "covered",
"hits": "2"
},
{
"id": "declaration/5/statement/6/body/tail/decision/false",
"outcome": "false",
"line": 41,
"state": "covered",
"hits": "93"
},
{
"id": "declaration/6/tail/decision/true",
"outcome": "true",
"line": 47,
"state": "covered",
"hits": "49"
},
{
"id": "declaration/6/tail/decision/false",
"outcome": "false",
"line": 47,
"state": "covered",
"hits": "42"
},
{
"id": "declaration/7/statement/1/decision/body",
"outcome": "body",
"line": 56,
"state": "covered",
"hits": "75"
},
{
"id": "declaration/7/statement/1/decision/exit",
"outcome": "exit",
"line": 56,
"state": "covered",
"hits": "18"
},
{
"id": "declaration/10/tail/decision/true",
"outcome": "true",
"line": 73,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/10/tail/decision/false",
"outcome": "false",
"line": 73,
"state": "covered",
"hits": "14014"
},
{
"id": "declaration/10/tail/false/tail/decision/true",
"outcome": "true",
"line": 75,
"state": "covered",
"hits": "7566"
},
{
"id": "declaration/10/tail/false/tail/decision/false",
"outcome": "false",
"line": 75,
"state": "covered",
"hits": "6448"
},
{
"id": "declaration/11/statement/1/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 88,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/statement/1/value/decision/skip-right",
"outcome": "skip-right",
"line": 88,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/4/decision/body",
"outcome": "body",
"line": 92,
"state": "covered",
"hits": "32"
},
{
"id": "declaration/11/statement/4/decision/exit",
"outcome": "exit",
"line": 92,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/statement/5/value/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 93,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/statement/5/value/decision/skip-right",
"outcome": "skip-right",
"line": 93,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/8/decision/body",
"outcome": "body",
"line": 96,
"state": "covered",
"hits": "38"
},
{
"id": "declaration/11/statement/8/decision/exit",
"outcome": "exit",
"line": 96,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/statement/8/body/tail/decision/true",
"outcome": "true",
"line": 97,
"state": "covered",
"hits": "38"
},
{
"id": "declaration/11/statement/8/body/tail/decision/false",
"outcome": "false",
"line": 97,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/8/body/tail/true/statement/5/value/decision/true",
"outcome": "true",
"line": 103,
"state": "covered",
"hits": "38"
},
{
"id": "declaration/11/statement/8/body/tail/true/statement/5/value/decision/false",
"outcome": "false",
"line": 103,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/decision/body",
"outcome": "body",
"line": 109,
"state": "covered",
"hits": "62"
},
{
"id": "declaration/11/statement/11/decision/exit",
"outcome": "exit",
"line": 109,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/statement/11/body/tail/decision/true",
"outcome": "true",
"line": 110,
"state": "covered",
"hits": "62"
},
{
"id": "declaration/11/statement/11/body/tail/decision/false",
"outcome": "false",
"line": 110,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/3/value/decision/true",
"outcome": "true",
"line": 114,
"state": "covered",
"hits": "62"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/3/value/decision/false",
"outcome": "false",
"line": 114,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/decision/body",
"outcome": "body",
"line": 115,
"state": "covered",
"hits": "718"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/decision/exit",
"outcome": "exit",
"line": 115,
"state": "covered",
"hits": "62"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/decision/true",
"outcome": "true",
"line": 118,
"state": "covered",
"hits": "718"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/decision/false",
"outcome": "false",
"line": 118,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 118,
"state": "covered",
"hits": "718"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/decision/skip-right",
"outcome": "skip-right",
"line": 118,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 118,
"state": "covered",
"hits": "718"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/left/decision/skip-right",
"outcome": "skip-right",
"line": 118,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/left/left/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 118,
"state": "covered",
"hits": "718"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/condition/left/left/decision/skip-right",
"outcome": "skip-right",
"line": 118,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/true/statement/3/value/args/1/decision/true",
"outcome": "true",
"line": 122,
"state": "covered",
"hits": "252"
},
{
"id": "declaration/11/statement/11/body/tail/true/statement/4/body/tail/true/statement/3/value/args/1/decision/false",
"outcome": "false",
"line": 122,
"state": "covered",
"hits": "466"
},
{
"id": "declaration/11/tail/decision/true",
"outcome": "true",
"line": 128,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/tail/decision/false",
"outcome": "false",
"line": 128,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/11/tail/condition/decision/evaluate-right",
"outcome": "evaluate-right",
"line": 128,
"state": "covered",
"hits": "8"
},
{
"id": "declaration/11/tail/condition/decision/skip-right",
"outcome": "skip-right",
"line": 128,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/12/tail/arm/0",
"outcome": "Error",
"line": 133,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/12/tail/arm/1",
"outcome": "Ok",
"line": 134,
"state": "covered",
"hits": "19"
},
{
"id": "declaration/12/tail/arm/1/body/arm/0",
"outcome": "Error",
"line": 135,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/12/tail/arm/1/body/arm/1",
"outcome": "Ok",
"line": 136,
"state": "covered",
"hits": "19"
},
{
"id": "declaration/13/tail/arm/0",
"outcome": "Error",
"line": 143,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/13/tail/arm/1",
"outcome": "Ok",
"line": 144,
"state": "covered",
"hits": "19"
},
{
"id": "declaration/14/statement/1/decision/body",
"outcome": "body",
"line": 152,
"state": "covered",
"hits": "19"
},
{
"id": "declaration/14/statement/1/decision/exit",
"outcome": "exit",
"line": 152,
"state": "covered",
"hits": "4"
},
{
"id": "declaration/14/statement/1/body/tail/decision/true",
"outcome": "true",
"line": 153,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/14/statement/1/body/tail/decision/false",
"outcome": "false",
"line": 153,
"state": "covered",
"hits": "19"
},
{
"id": "declaration/15/statement/1/decision/body",
"outcome": "body",
"line": 160,
"state": "covered",
"hits": "5836"
},
{
"id": "declaration/15/statement/1/decision/exit",
"outcome": "exit",
"line": 160,
"state": "covered",
"hits": "319"
},
{
"id": "declaration/16/statement/1/decision/body",
"outcome": "body",
"line": 166,
"state": "covered",
"hits": "64"
},
{
"id": "declaration/16/statement/1/decision/exit",
"outcome": "exit",
"line": 166,
"state": "covered",
"hits": "9"
},
{
"id": "declaration/16/statement/1/body/tail/decision/true",
"outcome": "true",
"line": 167,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/16/statement/1/body/tail/decision/false",
"outcome": "false",
"line": 167,
"state": "covered",
"hits": "59"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/decision/body",
"outcome": "body",
"line": 168,
"state": "covered",
"hits": "114"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/decision/exit",
"outcome": "exit",
"line": 168,
"state": "covered",
"hits": "5"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/body/tail/decision/true",
"outcome": "true",
"line": 169,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/body/tail/decision/false",
"outcome": "false",
"line": 169,
"state": "covered",
"hits": "113"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/body/tail/true/statement/1/value/decision/true",
"outcome": "true",
"line": 171,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/16/statement/1/body/tail/true/statement/0/body/tail/true/statement/1/value/decision/false",
"outcome": "false",
"line": 171,
"state": "covered",
"hits": "1"
},
{
"id": "declaration/17/tail/arm/0",
"outcome": "Error",
"line": 195,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/17/tail/arm/1",
"outcome": "Ok",
"line": 196,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/17/tail/arm/1/body/arm/0",
"outcome": "Ok",
"line": 197,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/17/tail/arm/1/body/arm/1",
"outcome": "Error",
"line": 198,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/18/tail/arm/0",
"outcome": "Error",
"line": 205,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/18/tail/arm/1",
"outcome": "Ok",
"line": 206,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/18/tail/arm/1/body/arm/0",
"outcome": "Error",
"line": 207,
"state": "zero",
"hits": "0"
},
{
"id": "declaration/18/tail/arm/1/body/arm/1",
"outcome": "Ok",
"line": 208,
"state": "zero",
"hits": "0"
}
]Reviewed declaration exclusions
[
{
"id": "declaration/0",
"reason": "import",
"line": 1
},
{
"id": "declaration/1",
"reason": "import",
"line": 2
},
{
"id": "declaration/2",
"reason": "record-declaration",
"line": 4
}
]