All files

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
  }
]