Skip to content

std/compiler

Compiler and analyzer operations for test tooling.

Import with import std/compiler.

struct Diagnostic {
    line: Int
    col: Int
    message: String
}

A compiler diagnostic with 1-based source coordinates.

impl Debug

fn inspect(value: Diagnostic): String

impl Debug.inspect

struct Hover {
    signature: String
    markdown: String
}

Hover text returned by the same renderer used by the editor.

impl Debug

fn inspect(value: Hover): String

impl Debug.inspect

struct Project {
    entry_point: String
    files: Map<String, String>
    manifest: Maybe<Toml>
}

An in-memory Nomi project for compiler tests.

entry_point names the module in files to check as the entry file. File keys are import paths without .nomi, so "main" represents main.nomi and "api/user" represents api/user.nomi.

manifest is optional nomi.toml content. When present, checks that depend on package metadata, such as entry_points, use it.

struct RunFile {
    entry_point: String
    env: Map<String, String>
}

Options for running a .nomi file under the current test project root.

fn check(source: String): List<Diagnostic>

Checks source as a standalone Nomi entry module and returns every diagnostic as data.

fn run(source: String): Result<String, String>

Runs source as a standalone Nomi entry module and captures stdout.

Err(message) is returned for parse, analysis, or runtime errors. Use Compiler.check when the diagnostic itself is the behavior under test; use Compiler.run when output is the behavior under test.

fn run_file(run: RunFile): Result<String, String>

Runs a .nomi file under the current test project root and captures stdout.

fn hover(source: String): Result<Hover, String>

Returns hover content for the single ˇ marker in source.

The marker is removed before parsing. Use it only in compiler/editor tests, where it marks the cursor position without making the fixture depend on line and column numbers.

fn check_project(project: Project): List<Diagnostic>

Checks an in-memory project and returns every diagnostic as data.

Interactive Tests

diagnostics = Compiler.check_project(Project{
  entry_point: "main",
  manifest: Maybe.Some(
    Toml"""
    [package]
    name = "demo"
    entry_points = ["main"]
    """
  ),
  files: {
    "main" => """
      import api: PublicApi.{Widget, make}

      fn main() {
        w = make("Ada")
        Widget.secret(w)
      }
      """,
    "api" => """
      pub module PublicApi

      pub struct Widget {
        field name: String

        fn secret(w: Widget): String {
          "secret " + w.name
        }
      }

      pub fn make(name: String): Widget {
        Widget{name}
      }
      """,
  },
})
assert [diagnostic] = diagnostics
assert String.contains?(diagnostic.message, "no member 'secret'")