Class CoverageProbePlacer

java.lang.Object
org.ek9lang.compiler.phase7.generation.CoverageProbePlacer

public final class CoverageProbePlacer extends Object
Places coverage probes at control flow points during IR generation.

Coverage probes are inserted at:

  • Function/method entry (FUNCTION_ENTRY)
  • If-then branch taken (BRANCH_TRUE)
  • Else/else-if branch taken (BRANCH_FALSE)
  • Switch case entry (SWITCH_CASE)
  • Catch block entry (CATCH_BLOCK)
  • Loop body entry (LOOP_BODY)

Each probe has a globally unique ID (GUID) generated from a deterministic FNV-1a 64-bit hash of its context (module, file, line, type, function). This ensures uniqueness across all source files without requiring coordination during parallel compilation.

Note: BLOCK and FUNCTION_EXIT probes are intentionally omitted as they are redundant in EK9 - explicit branch tracking already identifies paths taken, and EK9 functions have exactly one exit point (no return statement).

  • Constructor Details

    • CoverageProbePlacer

      public CoverageProbePlacer(CompilerFlags compilerFlags, long moduleId, String moduleName, boolean isDevSource)
      Create a coverage probe placer for a module.
      Parameters:
      compilerFlags - Compiler flags to check if coverage is enabled
      moduleId - Unique identifier for this module (unused, kept for API compatibility)
      moduleName - Human-readable module name
      isDevSource - True if this is dev/test source code (excluded from coverage)
  • Method Details

    • isCoverageEnabled

      public boolean isCoverageEnabled()
      Check if coverage instrumentation is enabled. Returns false for dev/test sources - like JaCoCo, we only measure coverage of production code, not the test harness code itself.
    • registerFileReadability

      public void registerFileReadability(String sourceFile, String readabilityScore)
      Register a file's readability score.

      ARI (Automated Readability Index) is calculated during parsing and provides a grade-level indicator of code readability. This is unique to EK9 - no competitor offers source code readability analysis.

      Parameters:
      sourceFile - Source file path
      readabilityScore - ARI score string (e.g., "10-11 Fifth Grade")
    • enterFunction

      public void enterFunction(String functionName, String simpleName, String sourceFile, int startLine)
      Enter a function/method context for probe tracking. Call this when starting to generate IR for a function/method.
      Parameters:
      functionName - Fully qualified function/method name
      simpleName - Simple function/method name (e.g., "_add")
      sourceFile - Source file containing this function
      startLine - Starting line number of the function
    • enterFunction

      public void enterFunction(String functionName, String simpleName, String sourceFile, int startLine, FunctionMetrics metrics)
      Enter a function/method context for probe tracking with metrics. Call this when starting to generate IR for a function/method.
      Parameters:
      functionName - Fully qualified function/method name
      simpleName - Simple function/method name (e.g., "_add")
      sourceFile - Source file containing this function
      startLine - Starting line number of the function
      metrics - Code quality metrics from Phase 5
    • setSignatureEndLine

      public void setSignatureEndLine(int signatureEndLine)
      Set the end line of the function signature.

      The signature includes the function name, parameters (->), and return declaration (<-). This allows HTML coverage reports to color all signature lines consistently based on the FUNCTION_ENTRY coverage status.

      Parameters:
      signatureEndLine - Last line of the function signature (after return declaration)
    • exitFunction

      public void exitFunction(int endLine)
      Exit the current function/method context. Records function-level coverage metadata.
      Parameters:
      endLine - Ending line number of the function body
    • createFunctionEntryProbe

      public IRInstr createFunctionEntryProbe(DebugInfo debugInfo)
      Create a function entry probe instruction.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createBranchTrueProbe

      public IRInstr createBranchTrueProbe(DebugInfo debugInfo)
      Create a branch-true (if/then) probe instruction.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createBranchFalseProbe

      public IRInstr createBranchFalseProbe(DebugInfo debugInfo)
      Create a branch-false (else) probe instruction.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createSwitchCaseProbe

      public IRInstr createSwitchCaseProbe(String caseLabel, DebugInfo debugInfo)
      Create a switch case probe instruction.
      Parameters:
      caseLabel - Label or description of the case (for logging purposes)
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createCatchBlockProbe

      public IRInstr createCatchBlockProbe(String exceptionType, DebugInfo debugInfo)
      Create a catch block probe instruction.
      Parameters:
      exceptionType - Type of exception being caught (for logging purposes)
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createLoopBodyProbe

      public IRInstr createLoopBodyProbe(DebugInfo debugInfo)
      Create a loop body probe instruction.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createFinallyBlockProbe

      public IRInstr createFinallyBlockProbe(DebugInfo debugInfo)
      Create a finally block probe instruction. Tracks execution of explicit finally blocks only.

      Note: Synthetic finally blocks (from try-with-resources without explicit finally) should NOT be probed because the close() method's FUNCTION_ENTRY already proves cleanup happened.

      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createStatementProbe

      public IRInstr createStatementProbe(DebugInfo debugInfo)
      Create a statement probe instruction. Tracks execution of individual statements for fine-grained coverage.

      Unlike edge-based tools that infer coverage, EK9 directly measures each statement execution. This ensures accurate coverage even when exceptions are thrown mid-block, and requires zero coverage logic in backends.

      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage probe instruction, or null if coverage disabled
    • createModuleRegistration

      public IRInstr createModuleRegistration(DebugInfo debugInfo)
      Create a module registration instruction. Should be emitted once per module in static initializer.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage register instruction
    • createCoverageFinalization

      public IRInstr createCoverageFinalization(DebugInfo debugInfo)
      Create a coverage finalization instruction. Should be emitted in the main program's shutdown hook or finally block.
      Parameters:
      debugInfo - Source location information
      Returns:
      Coverage finalize instruction
    • getProbeCount

      public int getProbeCount()
      Get the current probe count for this source file.
    • getModuleId

      public long getModuleId()
      Get the module ID (hash of module name).
    • getAllProbes

      public List<CoverageProbeDetails> getAllProbes()
      Get all probe details for this source file (for testing/verification).
    • getFunctionDetails

      public List<CoverageFunctionDetails> getFunctionDetails()
      Get function details for this source file (for testing/verification).
    • toMetadataJson

      public String toMetadataJson()
      Serialize probe and function metadata to JSON for runtime coverage computation.

      The JSON format is:

      {
        "probes": [
          {"id": "0x1234...", "type": "FUNCTION_ENTRY", "line": 10, "functionId": "0xABCD..."},
          {"id": "0x5678...", "type": "BRANCH_TRUE", "line": 15, "functionId": "0xABCD..."}
        ],
        "functions": [
          {"id": "0xABCD...", "name": "myFunction", "startLine": 10, "endLine": 20, "entryProbeId": "0x1234..."}
        ]
      }
      
      Returns:
      JSON string with coverage metadata, or null if no probes