ek9_compile

Compiles the workspace and answers status (ok | failed | found-no-sources | blocked), sourceCount, errorCount, warningCount and diagnostics[] - each with file, line, column, severity, errorCode and message, the ek9_query_diagnostics record - for every discovered .ek9 file.

Category: Execution · Compare: Build Project (IntelliJ)

When to use it

'Does the workspace compile, and what are the errors?' is one call: {} recompiles the initialised workspace, {projectDir:'.'} points it at a project root first.

When not to use it

Details

Two orthogonal dimensions: `mode` = cache strategy (default full; in V1 incremental/full/clean share the full-workspace compile path and only check-only differs - no artefacts) and artifact-intent flags (includeDev, withDebug, withProfiling, noLink, optimisation o0/o2-default/o3, phaseUpTo - any CompilationPhase name, default PRE_IR_CHECKS). Guards: includeDev implies withDebug; withProfiling implies withDebug and requires explicit optimisation:o0 (the o2 default blocks it); withDebug+o3 and withProfiling+noLink are blocked (status:'blocked' with a kebab-case reason). A success with zero discovered sources is status:'found-no-sources' (misconfigured projectDir); the .ek9 cache is not flag-keyed (use mode:full after switching debug/profile/opt). A failed compile with E07235 (fields but no '?') gets 'default operator ?' applied through the verified write and is compiled again - corrected[] and edits[] say where; repair:false only compiles.

Arguments

ArgumentTypeRequiredWhat it is
errorLevelintegerError detail level: 0 minimal, 1 visual, 2 + fuzzy suggestions, 3 + rich explanations.
includeDevbooleanInclude dev-only code (test sources, fixtures). Implies withDebug per the CLI -cd family bundling rule.
modestring: incremental | full | check-only | cleanCache strategy: incremental (recompile only changed files), full (re-emit all bytecode), check-only (compile + analyse without emitting artefacts), clean (wipe artefacts + dependencies before compile).
noLinkbooleanCompile + analyse without producing an executable artefact. Equivalent to mode: check-only when paired with mode: incremental or full. Rejected with withProfiling.
optimisationstring: o0 | o2 | o3o0 (none - fastest compile, max debug fidelity), o2 (balanced), o3 (aggressive - inlining, DCE, loop opts; breaks debug attributes and profiling probes). Auto-set to o0 when withProfiling: true.
phaseUpTostring: READING | PARSING | SYMBOL_DEFINITION | DUPLICATION_CHECK | REFERENCE_CHECKS | EXPLICIT_TYPE_SYMBOL_DEFINITION | TYPE_HIERARCHY_CHECKS | FULL_RESOLUTION | POST_RESOLUTION_CHECKS | PRE_IR_CHECKS | PLUGIN_RESOLUTION | SYMBOLIC_ANALYSIS | IR_GENERATION | IR_ANALYSIS | IR_OPTIMISATION | CODE_GENERATION_PREPARATION | CODE_GENERATION_CONSTANTS | CODE_GENERATION_APPLICATIONS | CODE_GENERATION_AGGREGATES | CODE_OPTIMISATION | PLUGIN_LINKAGE | APPLICATION_PACKAGING | PACKAGING_POST_PROCESSINGStop after the named compilation phase (e.g. FULL_RESOLUTION, IR_GENERATION) for pipeline-stage diagnostics.
projectDirstringProject root to discover .ek9 files from - absolute, or relative to the workspace root; (re)initialises the workspace before compiling. Omit to reuse the initialised workspace. Shorthand for roots:[projectDir].
repairbooleanApply the fixes the language leaves no choice about, then compile again: a slip with one reading (e.g. '-> a as Integer, b as String', 'Type?: value', a stray ')'), and 'default operator ?' for a class, record or component with fields and no '?' (E07235) - each listed in corrected[] and edits[]. false compiles only, and changes nothing.
rootsarray of stringSeveral project roots at once, each as projectDir. Omit for one root (use projectDir) or to reuse the initialised workspace.
traceCompilerbooleanEmit verbose compile-pipeline tracing to the build log.
withDebugbooleanEmit debug info / SMAP for breakpoint + variable inspection. Compatible with optimisation o0 (max fidelity) or o2 (safe). Rejected with o3 (aggressive optimisation strips debug attributes).
withProfilingbooleanEmit per-function profiling probes for hot-path / call-graph data. Forces optimisation: o0. Rejected with o2 / o3 (probes get inlined away). Rejected with noLink (no artefact to profile). Implies withDebug for source-line attribution.

Recorded calls

Real calls, recorded against small projects and checked on every build - a changed answer fails it. 3 of the 5 recorded are shown.

Pre ir checks shape

Request

{
  "phaseUpTo" : "PRE_IR_CHECKS",
  "roots" : [ "<workspace-root>" ]
}

Response

{
  "diagnostics" : [ ],
  "errorCount" : 0,
  "flags" : {
    "includeDev" : false,
    "mode" : "full",
    "noLink" : false,
    "optimisation" : "o2",
    "phaseUpTo" : "PRE_IR_CHECKS",
    "withDebug" : false,
    "withProfiling" : false
  },
  "meta" : {
    "serverMs" : "<timing>"
  },
  "sourceCount" : 1,
  "status" : "ok",
  "summary" : "Compilation succeeded (mode: full, phase: PRE_IR_CHECKS, optimisation: o2): 1 source, 0 errors, 0 warnings",
  "warningCount" : 0
}

Is set operator repaired in both modules

Request

{ }

Response

{
  "corrected" : [ "Point (alpha.ek9): added 'default operator ?' - a construct with fields must say when it is set (E07235), and 'default' means set only when every field is set. For a rule of your own, replace it with 'override operator ? as pure' and a body.", "Point (beta.ek9): added 'default operator ?' - a construct with fields must say when it is set (E07235), and 'default' means set only when every field is set. For a rule of your own, replace it with 'override operator ? as pure' and a body." ],
  "diagnostics" : [ ],
  "edits" : [ {
    "after" : "      default operator ?",
    "endLine" : 11,
    "file" : "alpha.ek9",
    "startLine" : 11,
    "type" : "insert"
  }, {
    "after" : "      default operator ?",
    "endLine" : 11,
    "file" : "beta.ek9",
    "startLine" : 11,
    "type" : "insert"
  } ],
  "errorCount" : 0,
  "flags" : {
    "includeDev" : false,
    "mode" : "full",
    "noLink" : false,
    "optimisation" : "o2",
    "phaseUpTo" : "PRE_IR_CHECKS",
    "withDebug" : false,
...

Cut short here: 10 more lines. The whole recorded call.

Is set operator applied then compiled

Request

{ }

Response (refused)

{
  "corrected" : [ "Basket (task.ek9): added 'default operator ?' - a construct with fields must say when it is set (E07235), and 'default' means set only when every field is set. For a rule of your own, replace it with 'override operator ? as pure' and a body." ],
  "diagnostics" : [ {
    "column" : 6,
    "errorCode" : "E08050",
    "file" : "task.ek9",
    "line" : 24,
    "message" : "❌ error   :[E08050]: '<-' on line 24 position 6: 'rtn': return value is not always initialised\n        ──▶ task.ek9:24:7\n        │\n     24 │       <- rtn as String?\n        │       ^^ '<-'\n        │\n        └─ 🔗 See: ek9 -h E08050\n",
    "richExplanation" : "[DIAGNOSIS]\nA function/method has a return variable that may not be initialized\non all possible execution paths.\n\n[EXAMPLES]\nCompilable examples demonstrating this error and the correct fix:\n  ek9 -q 688   (How does EK9 enforce variable initialization order?)\n\n[MUTATING OPERATORS ON RETURN PARAMETERS]\nReturn parameters declared without initialization (e.g., <- rtn as String?)\nCANNOT be used with mutating operators until initialized:\n\n- :=: (copy) and :~: (merge) - require existing value to copy/merge INTO\n- +=, -=, *=, /= etc. - require existing value to modify\n- ++, -- - require existing value to increment/decrement\n\n[A PATH THAT ENDS IN A THROW]\nA path that ends in an unconditional throw never returns, so it does not have to set the\nreturn variable - every arm of an if/else or switch that throws counts as covered. With\n'<- rtn as Integer?', an 'if' arm that assigns 'rtn: amount' and an 'else' arm that is just\n'throw Exception(\"Not positive\")' leave nothing unset.\nA throw inside an 'if' with no 'else' covers nothing (the other path still falls through),\nand a catch or finally that can run after the throw does not see the variable as set:\nreading it there is still E08020.\n\n[DYNAMIC FUNCTIONS]\nA dynamic function ('() extends SecurityGate as function', '() is Routine of (Boolean, Integer) as function')\ninherits its super's returning variable, but its body replaces the super's body - so the inherited variable\nstarts unassigned, whatever the super declared, and every path through the body must assign it. The error is\nreported at the dynamic function. Assign a default first (rtn: Boolean()), or assign on every branch.\n\n[ACTION]\n1. Initialize return parameter at declaration: <- rtn <- defaultValue\n2. Or use simple assignment (:) instead of mutating operators\n3. Or initialize before using mutating operators\n\n[COMMON CAUSES]\n- Return only set in some if branches (and the others neither set it nor throw)\n- A dynamic function setting its inherited return on only some paths\n- Using :=: or :~: on uninitialized return parameter\n- Loop might not execute\n- Expecting mutating operator to initialize\n\n[SEE ALSO]\n- E08050: return not initialized on all paths (this error)\n- E08020: variable used before initialized\n- E08060: variable might not be initialized",
    "severity" : "error"
  } ],
  "edits" : [ {
    "after" : "      default operator ?",
    "endLine" : 18,
    "file" : "task.ek9",
    "startLine" : 18,
    "type" : "insert"
  } ],
  "errorCount" : 1,
  "flags" : {
    "includeDev" : false,
    "mode" : "full",
    "noLink" : false,
    "optimisation" : "o2",
...

Cut short here: 13 more lines. The whole recorded call.

See also