kex docs Standard Library 0.4.0-alpha kex.run ↗

TaggedValidationprelude

module TaggedValidation

Diagnostics returned by compile-time validators for tagged literals.

A tagged literal (`` re`\d`` ``, `` sql`SELECT ...` ``) can be checked while your program is compiled rather than when it runs. The compiler finds the checker by name: a tag `foo` is validated by a function named `validateFoo` taking the literal's text and returning a list of `Issue` values. An empty list means the literal is fine.

let validateHex(source: String) -> [TaggedValidation.Issue] do
  match source.chars.findIndex { |c| !c.digit? && !c.in?('a'..'f') } do
    Just(offset) => [TaggedValidation.fatalAt(offset, "not a hex digit")]
    None         => []
  end
end

A `Fatal` issue stops the build with the message, pointing the caret at the offset; a `Warn+ reports without stopping.

Byte offsets are zero-based and relative to the cooked literal body.

type ByteSpan

Where in the literal an issue applies: a single offset, or a range.

Both are byte offsets into the literal body, counted from zero.

Variants

  • At(Integer)
  • Between(Integer, Integer)

type Issue

One diagnostic about a tagged literal.

Fatal stops the build; Warn reports and lets it continue. The span is optional: an issue about the literal as a whole carries None.

Variants

  • Fatal(ByteSpan?, String)
  • Warn(ByteSpan?, String)

function fatal

A fatal issue about the literal as a whole, with no particular position.

fatal(message) : String -> Issue
Parameters
message String
what is wrong

Returns: Issue — the diagnostic

Examples
TaggedValidation.fatal("an empty pattern matches nothing")

function fatalAt

A fatal issue at one offset in the literal.

The offset is where the caret points in the compiler's error, so use the position the underlying checker reported.

fatalAt(offset, message) : Integer -> String -> Issue
Parameters
offset Integer
the zero-based byte offset in the literal body
message String
what is wrong

Returns: Issue — the diagnostic

Examples
TaggedValidation.fatalAt(3, "missing closing parenthesis")

Reporting what a checker found

match Kex.Intrinsic.Regex.validate(source) do
  Just((offset, message)) => [TaggedValidation.fatalAt(offset, message)]
  None                    => []
end

function fatalBetween

A fatal issue spanning a range of the literal.

fatalBetween : Integer -> Integer -> String -> Issue
Parameters
start Integer
the first byte offset of the span
finish Integer
the offset just past its end
message String
what is wrong

Returns: Issue — the diagnostic

Examples
TaggedValidation.fatalBetween(0, 4, "this group can never match")

function warn

A warning about the literal as a whole. Reported, but the build continues.

warn(message) : String -> Issue
Parameters
message String
what is questionable

Returns: Issue — the diagnostic

Examples
TaggedValidation.warn("this pattern is very slow on long inputs")

function warnAt

A warning at one offset in the literal.

warnAt(offset, message) : Integer -> String -> Issue
Parameters
offset Integer
the zero-based byte offset in the literal body
message String
what is questionable

Returns: Issue — the diagnostic

Examples
TaggedValidation.warnAt(7, "redundant escape")

function warnBetween

A warning spanning a range of the literal.

warnBetween : Integer -> Integer -> String -> Issue
Parameters
start Integer
the first byte offset of the span
finish Integer
the offset just past its end
message String
what is questionable

Returns: Issue — the diagnostic

Examples
TaggedValidation.warnBetween(2, 6, "this alternation is always taken")