All files

src/compiler/loader.panack

Green: covered; red: known zero; amber: unavailable. Blank lines are outside the executable-start-line denominator.

    1 import "../bytecode/decoder.panack"
    2 import "module_bodies.panack"
    3 import "../stdlib/filesystem.panack"
    4 
    5 record ProjectLoadState {
    6   modules: [LoadedModule],
    7   visited: Set[Str],
    8   diagnostics: [Diagnostic],
    9   sources: Map[Str,Str],
   10   source_paths: [Str]
   11 }
   12 
   13 record LoadedProject {
   14   program: Program,
   15   modules: [LoadedModule],
   16   diagnostics: [Diagnostic],
   17   sources: Map[Str,Str],
   18   source_paths: [Str],
   19   evidence: [SubtractionEvidence],
   20   effects: [EffectEvidence],
   21   effects_checked: Bool,
   22   function_types: Map[Str,Bool],
   23   module_signatures: [ModuleSignature],
   24   module_bodies: [BoundFunctionBody]
   25 }
   26 
   27 pure path_in_stack(stack: [Str], path: Str): Bool {
   28   mut found: Bool = false
   29   for item in stack {
   30     if item == path { found = true; } else {}
   31   }
   32   found
   33 }
   34 
   35 pure loader_diagnostic(message: Str): Diagnostic {
   36   Diagnostic(message, SourcePos("", 0, 1, 1))
   37 }
   38 
   39 pure is_logical_import(path: Str): Bool {
   40   starts_with(path, "stdlib/") || starts_with(path, "project/")
   41 }
   42 
   43 pure logical_import_without_suffix(path: Str): Str {
   44   mut output: Str = ""
   45   mut index: Nat = 0
   46   while index < len(path) {
   47     if starts_with_at(path, ".panack", index) && index + len(".panack") == len(path) {
   48       index = len(path)
   49     } else {
   50       output = output + path[index]
   51       index = index + 1
   52     }
   53   }
   54   output
   55 }
   56 
   57 pure logical_import_segments_valid(path: Str): Bool {
   58   mut valid: Bool = len(path) > 0
   59   mut segment_start: Bool = true
   60   mut index: Nat = 0
   61   while index < len(path) {
   62     character: Str = path[index]
   63     if character == "/" {
   64       if segment_start { valid = false } else {}
   65       segment_start = true
   66     } else {
   67       if segment_start {
   68         if !(is_letter(character) || character == "_") { valid = false } else {}
   69         segment_start = false
   70       } else {
   71         if !(is_letter(character) || is_digit(character) || character == "_") { valid = false } else {}
   72       }
   73     }
   74     index = index + 1
   75   }
   76   valid && !segment_start
   77 }
   78 
   79 pure logical_import_valid(path: Str): Bool {
   80   suffix: Str = path_suffix(path)
   81   without_suffix: Str = logical_import_without_suffix(path)
   82   relative: Str = if starts_with(without_suffix, "stdlib/") {
   83     slice(without_suffix, len("stdlib/"), len(without_suffix))
   84   } else {
   85     if starts_with(without_suffix, "project/") {
   86       slice(without_suffix, len("project/"), len(without_suffix))
   87     } else {
   88       ""
   89     }
   90   }
   91   (suffix == "" || suffix == ".panack") && logical_import_segments_valid(relative)
   92 }
   93 
   94 pure resolve_import_path(imported: Str, parent: Str, project_root: Str, stdlib_root: Str): Str {
   95   if starts_with(imported, "stdlib/") {
   96     without_suffix: Str = logical_import_without_suffix(imported)
   97     relative: Str = slice(without_suffix, len("stdlib/"), len(without_suffix))
   98     path_join(stdlib_root, "${relative}.panack")
   99   } else {
  100     if starts_with(imported, "project/") {
  101       without_suffix: Str = logical_import_without_suffix(imported)
  102       relative: Str = slice(without_suffix, len("project/"), len(without_suffix))
  103       path_join(project_root, "${relative}.panack")
  104     } else {
  105       path_join(parent, imported)
  106     }
  107   }
  108 }
  109 
  110 read_project_source(path: Str, bounded: Bool, paths: [Str], sources: Map[Str,Str]): Result[Str,Str] {
  111   if !bounded { Ok(read_file(path)) }
  112   else {
  113     mut total: Nat = 0
  114     for loaded in paths { total = total + byte_len(utf8_encode(sources.get(loaded))); }
  115     if len(paths) >= 256 || total > 8388608 {
  116       Error("source-map source closure limit exceeded")
  117     } else {
  118       match path_from_text(path) {
  119         Error(error) => Error("invalid source path"),
  120         Ok(file) => match fs_read(file, 1048576) {
  121           Error(error) => Error("source-map source unavailable or exceeds 1 MiB"),
  122           Ok(data) => {
  123             if total + byte_len(data) > 8388608 { Error("source-map source closure exceeds 8 MiB") }
  124             else { if !valid_utf8(data) { Error("source-map source is not valid UTF-8") }
  125             else { Ok(utf8_decode(data)) } }
  126           }
  127         }
  128       }
  129     }
  130   }
  131 }
  132 
  133 load_project_module(path: Str, state: ProjectLoadState, stack: [Str], project_root: Str, stdlib_root: Str, bounded: Bool): ProjectLoadState {
  134   if state.visited.has(path) {
  135     state
  136   } else {
  137     if path_in_stack(stack, path) {
  138       diagnostics: [Diagnostic] = append(state.diagnostics, loader_diagnostic("import cycle includes ${path}"))
  139       ProjectLoadState(state.modules, state.visited, diagnostics, state.sources, state.source_paths)
  140     } else {
  141       if path_suffix(path) != ".panack" {
  142         diagnostics: [Diagnostic] = append(state.diagnostics, loader_diagnostic("import must reference a .panack file: ${path}"))
  143         ProjectLoadState(state.modules, state.visited, diagnostics, state.sources, state.source_paths)
  144       } else {
  145         if !file_exists(path) {
  146           diagnostics: [Diagnostic] = append(state.diagnostics, loader_diagnostic("missing source module ${path}"))
  147           ProjectLoadState(state.modules, state.visited, diagnostics, state.sources, state.source_paths)
  148         } else {
  149           match read_project_source(path, bounded, state.source_paths, state.sources) {
  150             Error(message) => ProjectLoadState(state.modules, state.visited, append(state.diagnostics, loader_diagnostic(message + ": " + path)), state.sources, state.source_paths),
  151             Ok(source) => {
  152               paths: [Str] = append(state.source_paths, path)
  153               sources: Map[Str,Str] = state.sources.put(path, source)
  154               match lex_file(source, path) {
  155                 Error(errors) => {
  156                   mut diagnostics: [Diagnostic] = state.diagnostics
  157                   for error in errors {
  158                     diagnostics = append(diagnostics, error)
  159                   }
  160                   ProjectLoadState(state.modules, state.visited.add(path), diagnostics, sources, paths)
  161                 },
  162                 Ok(tokens) => {
  163                   match parse_module_complete(tokens) {
  164                     Error(error) => {
  165                       diagnostics: [Diagnostic] = append(state.diagnostics, error)
  166                       ProjectLoadState(state.modules, state.visited.add(path), diagnostics, sources, paths)
  167                     },
  168                     Ok(parsed) => {
  169                       identity: ModuleIdentity = source_module_identity(path, project_root, stdlib_root)
  170                       bindings: ModuleBindings = collect_module_bindings(identity, parsed)
  171                       // Retain original source bindings before the existing core-only
  172                       // callable internalization used by the execution frontend.
  173                       program: Program = if path == path_join(stdlib_root, "core.panack") {
  174                         match parse_module_complete(core_tokens(tokens)) {
  175                           Ok(internal) => lower_legacy_program(internal.program),
  176                           Error(error) => lower_legacy_program(parsed.program)
  177                         }
  178                       } else { lower_legacy_program(parsed.program) }
  179                       module: LoadedModule = LoadedModule(path, parsed, program, bindings)
  180                       staged: [Diagnostic] = module_execution_diagnostics(parsed)
  181                       binding_errors: [Diagnostic] = if len(staged) > 0 { module_binding_diagnostics(bindings) } else { [] }
  182                       mut current: ProjectLoadState = ProjectLoadState(state.modules, state.visited, concat(state.diagnostics, concat(binding_errors, staged)), sources, paths)
  183                       next_stack: [Str] = append(stack, path)
  184                       for declaration in program.declarations {
  185                         match declaration {
  186                           ImportDeclaration(imported) => {
  187                             if is_logical_import(imported) {
  188                               if !logical_import_valid(imported) {
  189                                 diagnostics: [Diagnostic] = append(current.diagnostics, loader_diagnostic("invalid logical import path: ${imported}"))
  190                                 current = ProjectLoadState(current.modules, current.visited, diagnostics, current.sources, current.source_paths)
  191                               } else {
  192                                 if starts_with(imported, "stdlib/") && len(stdlib_root) == 0 {
  193                                   diagnostics: [Diagnostic] = append(current.diagnostics, loader_diagnostic("standard library root is not configured"))
  194                                   current = ProjectLoadState(current.modules, current.visited, diagnostics, current.sources, current.source_paths)
  195                                 } else {
  196                                   parent: Str = path_parent(path)
  197                                   dependency: Str = resolve_import_path(imported, parent, project_root, stdlib_root)
  198                                   current = load_project_module(dependency, current, next_stack, project_root, stdlib_root, bounded)
  199                                 }
  200                               }
  201                             } else {
  202                               if path_is_absolute(imported) {
  203                                 diagnostics: [Diagnostic] = append(current.diagnostics, loader_diagnostic("imports must use relative or logical paths: ${imported}"))
  204                                 current = ProjectLoadState(current.modules, current.visited, diagnostics, current.sources, current.source_paths)
  205                               } else {
  206                                 if path_suffix(imported) != ".panack" {
  207                                   diagnostics: [Diagnostic] = append(current.diagnostics, loader_diagnostic("relative import must reference a .panack file: ${imported}"))
  208                                   current = ProjectLoadState(current.modules, current.visited, diagnostics, current.sources, current.source_paths)
  209                                 } else {
  210                                   parent: Str = path_parent(path)
  211                                   dependency: Str = resolve_import_path(imported, parent, project_root, stdlib_root)
  212                                   current = load_project_module(dependency, current, next_stack, project_root, stdlib_root, bounded)
  213                                 }
  214                               }
  215                             }
  216                           },
  217                           TypeDeclaration(name, base, guard) => {},
  218                           RecordDeclaration(name, parameters, fields) => {},
  219                           EnumDeclaration(name, parameters, variants) => {},
  220                           FunctionDeclaration(name, parameters, return_type, is_pure, is_async, body, type_parameters) => {}
  221                         }
  222                       }
  223                       modules: [LoadedModule] = append(current.modules, module)
  224                       ProjectLoadState(modules, current.visited.add(path), current.diagnostics, current.sources, current.source_paths)
  225                     }
  226                   }
  227                 }
  228               }
  229             }
  230           }
  231         }
  232       }
  233     }
  234   }
  235 }
  236 
  237 load_project(entry: Str): LoadedProject {
  238   load_project_mode(entry, false, false)
  239 }
  240 
  241 load_project_for_source_map(entry: Str): LoadedProject {
  242   load_project_mode(entry, true, false)
  243 }
  244 
  245 load_project_explained(entry: Str): LoadedProject {
  246   load_project_mode(entry, true, true)
  247 }
  248 
  249 load_project_for_inventory(entry: Str): LoadedProject {
  250   load_project_mode_with_main(entry, true, false, false)
  251 }
  252 
  253 load_project_mode(entry: Str, bounded: Bool, retain: Bool): LoadedProject {
  254   load_project_mode_with_main(entry, bounded, retain, true)
  255 }
  256 
  257 load_project_mode_with_main(entry: Str, bounded: Bool, retain: Bool, require_main: Bool): LoadedProject {
  258   resolved: Str = path_resolve(entry)
  259   project_root: Str = path_parent(resolved)
  260   stdlib_root: Str = if environment_has("PANACKELTY_STDLIB_PATH") {
  261     path_resolve(environment_get("PANACKELTY_STDLIB_PATH"))
  262   } else {
  263     ""
  264   }
  265   empty: Set[Str] = set()
  266   initial: ProjectLoadState = ProjectLoadState([], empty, [], map(), [])
  267   stack: [Str] = []
  268   mut core: ProjectLoadState = initial
  269   if len(stdlib_root) == 0 {
  270     core = ProjectLoadState([], empty, [loader_diagnostic("standard library root is not configured; core types require the bundled standard library")], map(), [])
  271   } else {
  272     core = load_project_module(path_join(stdlib_root, "core.panack"), initial, stack, project_root, stdlib_root, bounded)
  273   }
  274   loaded: ProjectLoadState = if len(core.diagnostics) == 0 {
  275     load_project_module(resolved, core, stack, project_root, stdlib_root, bounded)
  276   } else { core }
  277   program: Program = append_program_declarations(module_programs(loaded.modules))
  278   mut diagnostics: [Diagnostic] = loaded.diagnostics
  279   mut signatures: [ModuleSignature] = []
  280   mut bodies: [BoundFunctionBody] = []
  281   mut staged: Bool = false
  282   for module in loaded.modules { staged = staged || len(module_execution_diagnostics(module.parsed)) > 0 }
  283   if staged {
  284     graph: ModuleBindingGraph = loaded_binding_graph(loaded.modules, project_root, stdlib_root)
  285     graph_errors: [Diagnostic] = module_graph_diagnostics(graph)
  286     diagnostics = concat(diagnostics, graph_errors)
  287     if len(graph_errors) == 0 {
  288       // Complete contracts before bodies: source/import order and recursion
  289       // cannot select a different callable identity or miss a later contract.
  290       for module in loaded.modules {
  291         checked_signatures: CheckedModuleSignatures = check_module_signatures(graph, loaded.modules, module)
  292         signatures = concat(signatures, checked_signatures.declarations)
  293         if len(module_execution_diagnostics(module.parsed)) > 0 {
  294           diagnostics = concat(diagnostics, checked_signatures.diagnostics)
  295         }
  296       }
  297       for module in loaded.modules {
  298         if len(module_execution_diagnostics(module.parsed)) > 0 {
  299           checked_bodies: CheckedModuleBodies = check_module_bodies(graph, loaded.modules, signatures, module)
  300           diagnostics = concat(diagnostics, checked_bodies.diagnostics)
  301           bodies = concat(bodies, checked_bodies.functions)
  302         }
  303       }
  304     }
  305   }
  306   if len(diagnostics) == 0 {
  307     diagnostics = concat(diagnostics, resolve_program_at(program, module_declaration_positions(loaded.modules)))
  308   } else {}
  309   mut evidence: [SubtractionEvidence] = []
  310   mut effects: [EffectEvidence] = []
  311   mut effects_checked: Bool = false
  312   mut function_types: Map[Str,Bool] = map()
  313   if len(diagnostics) == 0 {
  314     checked: CheckedProgram = check_program_evidence_mode(program, retain, require_main)
  315     checked_effects: CheckedEffects = check_frontend_effects(program, checked, retain)
  316     diagnostics = checked_effects.diagnostics
  317     evidence = checked.evidence
  318     effects = checked_effects.evidence
  319     function_types = checked.function_types
  320     effects_checked = len(checked.diagnostics) == 0 || (retain && checked.declarations_valid)
  321   }
  322   LoadedProject(program, loaded.modules, diagnostics, loaded.sources, loaded.source_paths, evidence, effects, effects_checked, function_types, signatures, bodies)
  323 }
  324 
  325 // Build semantic edges only from the loader's normalized path decisions.
  326 pure loaded_binding_graph(modules: [LoadedModule], project_root: Str, stdlib_root: Str): ModuleBindingGraph {
  327   mut bindings: [ModuleBindings] = []
  328   mut edges: [ModuleImportEdge] = []
  329   for module in modules {
  330     bindings = append(bindings, module.bindings)
  331     mut index: Nat = 0
  332     for imported in module.bindings.imports {
  333       path: Str = resolve_import_path(imported.path, path_parent(module.source_path), project_root, stdlib_root)
  334       edges = append(edges, ModuleImportEdge(module.bindings.identity, index, source_module_identity(path, project_root, stdlib_root)))
  335       index = index + 1
  336     }
  337   }
  338   ModuleBindingGraph(bindings, edges)
  339 }
  340 

Functions

[
  {
    "id": "declaration/5",
    "name": "path_in_stack",
    "line": 27,
    "state": "covered",
    "entries": "90"
  },
  {
    "id": "declaration/6",
    "name": "loader_diagnostic",
    "line": 35,
    "state": "zero",
    "entries": "0"
  },
  {
    "id": "declaration/7",
    "name": "is_logical_import",
    "line": 39,
    "state": "covered",
    "entries": "67"
  },
  {
    "id": "declaration/8",
    "name": "logical_import_without_suffix",
    "line": 43,
    "state": "covered",
    "entries": "4"
  },
  {
    "id": "declaration/9",
    "name": "logical_import_segments_valid",
    "line": 57,
    "state": "covered",
    "entries": "2"
  },
  {
    "id": "declaration/10",
    "name": "logical_import_valid",
    "line": 79,
    "state": "covered",
    "entries": "2"
  },
  {
    "id": "declaration/11",
    "name": "resolve_import_path",
    "line": 94,
    "state": "covered",
    "entries": "67"
  },
  {
    "id": "declaration/12",
    "name": "read_project_source",
    "line": 110,
    "state": "covered",
    "entries": "92"
  },
  {
    "id": "declaration/13",
    "name": "load_project_module",
    "line": 133,
    "state": "covered",
    "entries": "105"
  },
  {
    "id": "declaration/14",
    "name": "load_project",
    "line": 237,
    "state": "covered",
    "entries": "12"
  },
  {
    "id": "declaration/15",
    "name": "load_project_for_source_map",
    "line": 241,
    "state": "covered",
    "entries": "5"
  },
  {
    "id": "declaration/16",
    "name": "load_project_explained",
    "line": 245,
    "state": "zero",
    "entries": "0"
  },
  {
    "id": "declaration/17",
    "name": "load_project_for_inventory",
    "line": 249,
    "state": "covered",
    "entries": "2"
  },
  {
    "id": "declaration/18",
    "name": "load_project_mode",
    "line": 253,
    "state": "covered",
    "entries": "17"
  },
  {
    "id": "declaration/19",
    "name": "load_project_mode_with_main",
    "line": 257,
    "state": "covered",
    "entries": "19"
  },
  {
    "id": "declaration/20",
    "name": "loaded_binding_graph",
    "line": 326,
    "state": "zero",
    "entries": "0"
  }
]

Source branch outcomes

[
  {
    "id": "declaration/5/statement/1/decision/body",
    "outcome": "body",
    "line": 29,
    "state": "covered",
    "hits": "204"
  },
  {
    "id": "declaration/5/statement/1/decision/exit",
    "outcome": "exit",
    "line": 29,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/5/statement/1/body/tail/decision/true",
    "outcome": "true",
    "line": 30,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/5/statement/1/body/tail/decision/false",
    "outcome": "false",
    "line": 30,
    "state": "covered",
    "hits": "204"
  },
  {
    "id": "declaration/7/tail/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 40,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/7/tail/decision/skip-right",
    "outcome": "skip-right",
    "line": 40,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/8/statement/2/decision/body",
    "outcome": "body",
    "line": 46,
    "state": "covered",
    "hits": "56"
  },
  {
    "id": "declaration/8/statement/2/decision/exit",
    "outcome": "exit",
    "line": 46,
    "state": "covered",
    "hits": "4"
  },
  {
    "id": "declaration/8/statement/2/body/tail/decision/true",
    "outcome": "true",
    "line": 47,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/8/statement/2/body/tail/decision/false",
    "outcome": "false",
    "line": 47,
    "state": "covered",
    "hits": "56"
  },
  {
    "id": "declaration/8/statement/2/body/tail/condition/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 47,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/8/statement/2/body/tail/condition/decision/skip-right",
    "outcome": "skip-right",
    "line": 47,
    "state": "covered",
    "hits": "56"
  },
  {
    "id": "declaration/9/statement/3/decision/body",
    "outcome": "body",
    "line": 61,
    "state": "covered",
    "hits": "14"
  },
  {
    "id": "declaration/9/statement/3/decision/exit",
    "outcome": "exit",
    "line": 61,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/decision/true",
    "outcome": "true",
    "line": 63,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/decision/false",
    "outcome": "false",
    "line": 63,
    "state": "covered",
    "hits": "14"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/true/statement/0/value/decision/true",
    "outcome": "true",
    "line": 64,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/true/statement/0/value/decision/false",
    "outcome": "false",
    "line": 64,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/decision/true",
    "outcome": "true",
    "line": 67,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/decision/false",
    "outcome": "false",
    "line": 67,
    "state": "covered",
    "hits": "12"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/true/statement/0/value/decision/true",
    "outcome": "true",
    "line": 68,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/true/statement/0/value/decision/false",
    "outcome": "false",
    "line": 68,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/true/statement/0/value/condition/operand/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 68,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/true/statement/0/value/condition/operand/decision/skip-right",
    "outcome": "skip-right",
    "line": 68,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 71,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 71,
    "state": "covered",
    "hits": "12"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/condition/operand/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 71,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/condition/operand/decision/skip-right",
    "outcome": "skip-right",
    "line": 71,
    "state": "covered",
    "hits": "12"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/condition/operand/left/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 71,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/9/statement/3/body/statement/1/value/false/tail/false/tail/condition/operand/left/decision/skip-right",
    "outcome": "skip-right",
    "line": 71,
    "state": "covered",
    "hits": "12"
  },
  {
    "id": "declaration/9/tail/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 76,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/9/tail/decision/skip-right",
    "outcome": "skip-right",
    "line": 76,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/statement/2/value/decision/true",
    "outcome": "true",
    "line": 82,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/10/statement/2/value/decision/false",
    "outcome": "false",
    "line": 82,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/statement/2/value/false/tail/decision/true",
    "outcome": "true",
    "line": 85,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/statement/2/value/false/tail/decision/false",
    "outcome": "false",
    "line": 85,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/tail/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 91,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/10/tail/decision/skip-right",
    "outcome": "skip-right",
    "line": 91,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/tail/left/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 91,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/10/tail/left/decision/skip-right",
    "outcome": "skip-right",
    "line": 91,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/11/tail/decision/true",
    "outcome": "true",
    "line": 95,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/11/tail/decision/false",
    "outcome": "false",
    "line": 95,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/11/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 100,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/11/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 100,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/12/tail/decision/true",
    "outcome": "true",
    "line": 111,
    "state": "covered",
    "hits": "63"
  },
  {
    "id": "declaration/12/tail/decision/false",
    "outcome": "false",
    "line": 111,
    "state": "covered",
    "hits": "29"
  },
  {
    "id": "declaration/12/tail/false/statement/1/decision/body",
    "outcome": "body",
    "line": 114,
    "state": "covered",
    "hits": "343"
  },
  {
    "id": "declaration/12/tail/false/statement/1/decision/exit",
    "outcome": "exit",
    "line": 114,
    "state": "covered",
    "hits": "29"
  },
  {
    "id": "declaration/12/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 115,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/12/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 115,
    "state": "covered",
    "hits": "27"
  },
  {
    "id": "declaration/12/tail/false/tail/condition/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 115,
    "state": "covered",
    "hits": "28"
  },
  {
    "id": "declaration/12/tail/false/tail/condition/decision/skip-right",
    "outcome": "skip-right",
    "line": 115,
    "state": "covered",
    "hits": "1"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/0",
    "outcome": "Error",
    "line": 119,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1",
    "outcome": "Ok",
    "line": 120,
    "state": "covered",
    "hits": "27"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/0",
    "outcome": "Error",
    "line": 121,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/1",
    "outcome": "Ok",
    "line": 122,
    "state": "covered",
    "hits": "27"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/1/body/block/tail/decision/true",
    "outcome": "true",
    "line": 123,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/1/body/block/tail/decision/false",
    "outcome": "false",
    "line": 123,
    "state": "covered",
    "hits": "27"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/1/body/block/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 124,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/12/tail/false/tail/false/tail/arm/1/body/arm/1/body/block/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 124,
    "state": "covered",
    "hits": "27"
  },
  {
    "id": "declaration/13/tail/decision/true",
    "outcome": "true",
    "line": 134,
    "state": "covered",
    "hits": "15"
  },
  {
    "id": "declaration/13/tail/decision/false",
    "outcome": "false",
    "line": 134,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 137,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 137,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 141,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 141,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 145,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 145,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/0",
    "outcome": "Error",
    "line": 150,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1",
    "outcome": "Ok",
    "line": 151,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/0",
    "outcome": "Error",
    "line": 155,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/0/body/block/statement/1/decision/body",
    "outcome": "body",
    "line": 157,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/0/body/block/statement/1/decision/exit",
    "outcome": "exit",
    "line": 157,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1",
    "outcome": "Ok",
    "line": 162,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/0",
    "outcome": "Error",
    "line": 164,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1",
    "outcome": "Ok",
    "line": 168,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/2/value/decision/true",
    "outcome": "true",
    "line": 173,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/2/value/decision/false",
    "outcome": "false",
    "line": 173,
    "state": "covered",
    "hits": "71"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/2/value/true/tail/arm/0",
    "outcome": "Ok",
    "line": 175,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/2/value/true/tail/arm/1",
    "outcome": "Error",
    "line": 176,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/5/value/decision/true",
    "outcome": "true",
    "line": 181,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/5/value/decision/false",
    "outcome": "false",
    "line": 181,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/decision/body",
    "outcome": "body",
    "line": 184,
    "state": "covered",
    "hits": "905"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/decision/exit",
    "outcome": "exit",
    "line": 184,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0",
    "outcome": "ImportDeclaration",
    "line": 186,
    "state": "covered",
    "hits": "67"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/decision/true",
    "outcome": "true",
    "line": 187,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/decision/false",
    "outcome": "false",
    "line": 187,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/decision/true",
    "outcome": "true",
    "line": 188,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/decision/false",
    "outcome": "false",
    "line": 188,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 192,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 192,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/false/tail/condition/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 192,
    "state": "covered",
    "hits": "2"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/true/tail/false/tail/condition/decision/skip-right",
    "outcome": "skip-right",
    "line": 192,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 202,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 202,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/false/tail/false/tail/decision/true",
    "outcome": "true",
    "line": 206,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/0/body/block/tail/false/tail/false/tail/decision/false",
    "outcome": "false",
    "line": 206,
    "state": "covered",
    "hits": "65"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/1",
    "outcome": "TypeDeclaration",
    "line": 217,
    "state": "covered",
    "hits": "3"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/2",
    "outcome": "RecordDeclaration",
    "line": 218,
    "state": "covered",
    "hits": "122"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/3",
    "outcome": "EnumDeclaration",
    "line": 219,
    "state": "covered",
    "hits": "72"
  },
  {
    "id": "declaration/13/tail/false/tail/false/tail/false/tail/false/tail/arm/1/body/block/tail/arm/1/body/block/tail/arm/1/body/block/statement/8/body/tail/arm/4",
    "outcome": "FunctionDeclaration",
    "line": 220,
    "state": "covered",
    "hits": "641"
  },
  {
    "id": "declaration/19/statement/2/value/decision/true",
    "outcome": "true",
    "line": 260,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/2/value/decision/false",
    "outcome": "false",
    "line": 260,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/7/value/decision/true",
    "outcome": "true",
    "line": 269,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/7/value/decision/false",
    "outcome": "false",
    "line": 269,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/8/value/decision/true",
    "outcome": "true",
    "line": 274,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/8/value/decision/false",
    "outcome": "false",
    "line": 274,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/14/decision/body",
    "outcome": "body",
    "line": 282,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/19/statement/14/decision/exit",
    "outcome": "exit",
    "line": 282,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/14/body/statement/0/value/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 282,
    "state": "covered",
    "hits": "90"
  },
  {
    "id": "declaration/19/statement/14/body/statement/0/value/decision/skip-right",
    "outcome": "skip-right",
    "line": 282,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/decision/true",
    "outcome": "true",
    "line": 283,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/decision/false",
    "outcome": "false",
    "line": 283,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/decision/true",
    "outcome": "true",
    "line": 287,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/decision/false",
    "outcome": "false",
    "line": 287,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/0/decision/body",
    "outcome": "body",
    "line": 290,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/0/decision/exit",
    "outcome": "exit",
    "line": 290,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/0/body/tail/decision/true",
    "outcome": "true",
    "line": 293,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/0/body/tail/decision/false",
    "outcome": "false",
    "line": 293,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/1/decision/body",
    "outcome": "body",
    "line": 297,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/1/decision/exit",
    "outcome": "exit",
    "line": 297,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/1/body/tail/decision/true",
    "outcome": "true",
    "line": 298,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/15/value/true/tail/true/statement/1/body/tail/decision/false",
    "outcome": "false",
    "line": 298,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/16/value/decision/true",
    "outcome": "true",
    "line": 306,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/16/value/decision/false",
    "outcome": "false",
    "line": 306,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/21/value/decision/true",
    "outcome": "true",
    "line": 313,
    "state": "covered",
    "hits": "19"
  },
  {
    "id": "declaration/19/statement/21/value/decision/false",
    "outcome": "false",
    "line": 313,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/21/value/true/statement/6/value/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 320,
    "state": "covered",
    "hits": "1"
  },
  {
    "id": "declaration/19/statement/21/value/true/statement/6/value/decision/skip-right",
    "outcome": "skip-right",
    "line": 320,
    "state": "covered",
    "hits": "18"
  },
  {
    "id": "declaration/19/statement/21/value/true/statement/6/value/right/decision/evaluate-right",
    "outcome": "evaluate-right",
    "line": 320,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/19/statement/21/value/true/statement/6/value/right/decision/skip-right",
    "outcome": "skip-right",
    "line": 320,
    "state": "covered",
    "hits": "1"
  },
  {
    "id": "declaration/20/statement/2/decision/body",
    "outcome": "body",
    "line": 329,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/20/statement/2/decision/exit",
    "outcome": "exit",
    "line": 329,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/20/statement/2/body/statement/2/decision/body",
    "outcome": "body",
    "line": 332,
    "state": "zero",
    "hits": "0"
  },
  {
    "id": "declaration/20/statement/2/body/statement/2/decision/exit",
    "outcome": "exit",
    "line": 332,
    "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": "import",
    "line": 3
  },
  {
    "id": "declaration/3",
    "reason": "record-declaration",
    "line": 5
  },
  {
    "id": "declaration/4",
    "reason": "record-declaration",
    "line": 13
  }
]