///|
/// The version of smithy-syntax, the same as `version` in `moon.mod`.
pub fn version() -> String {
"0.0.1"
}
///|
/// Spans (UTF-16 unit offsets), positions and source text.
pub using @span {
type Span,
type Offset,
type Length,
type Line,
type Column,
type Position,
type SourceText,
}
///|
/// Diagnostics: severity, labels and the problem record.
pub using @diagnostic {type Severity, type Label, type Diagnostic}
///|
/// The one-line description of a diagnostic code, or `None`.
pub fn diagnostic_description(code : String) -> String? {
@diagnostic.description(code)
}
///|
/// The scanner: tokens, trivia and lexical errors.
pub using @scanner {
type TokenStream,
type Token,
type TokenKind,
type Trivia,
type Comment,
type CommentKind,
type Piece,
type Step,
}
///|
/// Scan `source` into tokens with trivia. Lossless: `to_source()` is the text.
pub fn tokenize(source : SourceText) -> TokenStream {
@scanner.tokenize(source)
}
///|
/// The AST.
pub using @ast {
type IdlFile,
type ControlStatement,
type MetadataStatement,
type NamespaceStatement,
type UseStatement,
type Statement,
type ShapeStatement,
type ApplyStatement,
type Shape,
type ShapeKind,
type SimpleType,
type EnumType,
type AggregateType,
type EntityType,
type Mixins,
type Trait,
type TraitBody,
type Member,
type MemberTarget,
type EnumMember,
type InlineShape,
type OperationTarget,
type OperationProperty,
type NodeValue,
type NodeKvp,
type NumberLiteral,
type NumberValue,
type Keyword,
type ShapeId,
type DocComment,
type Node,
}
///|
/// The CST: every token grouped per statement.
pub using @cst {type IdlCst, type StatementCst, type StatementKind}
///|
/// The parser's result, version, recursion depth and error.
pub using @parser {type ParseResult, type ParseError, type Version, type Depth}
///|
/// The traversal: the node model, the cursor, the tree and the event types.
pub using @traversal {
type NodeRef,
type Control,
type PathStep,
type NodePath,
type EnterEvent,
type LeaveEvent,
type Event,
type EventReader,
type Tree,
type TreeCursor,
trait EventSource,
trait Handler,
trait Visitor,
}
///|
/// Visit `root` and every node below it in pre-order; see `@traversal.walk`.
pub fn walk(
root : NodeRef,
enter : (NodeRef) -> Control,
leave~ : (NodeRef) -> Unit = _ => (),
) -> Unit {
@traversal.walk(root, enter, leave~)
}
///|
/// Thread an accumulator through a walk; see `@traversal.fold`.
pub fn[A] fold(
root : NodeRef,
init : A,
enter : (A, NodeRef) -> (A, Control),
leave~ : (A, NodeRef) -> A = (a, _) => a,
) -> A {
@traversal.fold(root, init, enter, leave~)
}
///|
/// Reduce `root` bottom up; see `@traversal.reduce`.
pub fn[R] reduce(root : NodeRef, f : (NodeRef, ArrayView[R]) -> R) -> R {
@traversal.reduce(root, f)
}
///|
/// Reduce bottom up, steered by `enter`; see `@traversal.reduce_pruned`.
pub fn[R] reduce_pruned(
root : NodeRef,
enter : (NodeRef) -> Control,
f : (NodeRef, ArrayView[R]) -> R,
) -> R? {
@traversal.reduce_pruned(root, enter, f)
}
///|
/// Call one `Visitor` method per node; see `@traversal.accept`.
pub fn[V : Visitor] accept(root : NodeRef, visitor : V) -> Unit {
@traversal.accept(root, visitor)
}
///|
/// Drive an event source into a handler; see `@traversal.push_events`.
pub fn[S : EventSource, H : Handler] push_events(
source : S,
handler : H,
) -> Unit {
@traversal.push_events(source, handler)
}
///|
/// Every node type: (category, kind, fields); see `@traversal.kind_table`.
pub fn kind_table() -> Array[(String, String, Array[String])] {
@traversal.kind_table()
}
///|
/// Parse a source text with recovery per statement.
pub fn parse(source : SourceText) -> ParseResult {
@parser.parse(source)
}
///|
/// Parse Smithy IDL text. `name` is shown in rendered diagnostics.
///
/// ```mbt check
/// test {
/// let r = @syntax.parse_idl(
/// (
/// #|$version: "2"
/// #|namespace com.foo
/// #|
/// #|string Name
/// #|
/// ),
/// name="a.smithy",
/// )
/// inspect(r.has_errors(), content="false")
/// }
/// ```
pub fn parse_idl(text : String, name? : String) -> ParseResult {
@parser.parse(@span.SourceText::new(text, name?))
}
///|
/// Render one diagnostic as a single line, for editors (`path:line:col:
/// severity[code]: message`).
pub fn render_short(d : Diagnostic, source : SourceText) -> String {
@report.render_short(d, source)
}
///|
/// Render one diagnostic without colour, as the Elm/Rust-style layout.
pub fn render_plain(d : Diagnostic, source : SourceText) -> String {
@report.render_plain(d, source)
}
///|
/// Render one diagnostic for a terminal, with ANSI colour by default.
pub fn render_terminal(
d : Diagnostic,
source : SourceText,
color~ : Bool = true,
) -> String {
@report.render_terminal(d, source, color~)
}
///|
/// Render into any core `Logger`, for callers with their own sink.
pub fn render_terminal_to(
d : Diagnostic,
source : SourceText,
logger : &Logger,
color~ : Bool = true,
) -> Unit {
@report.render_terminal_to(d, source, logger, color~)
}
///|
/// Render every diagnostic in order, ending with an error/warning count.
pub fn render_all(
ds : ArrayView[Diagnostic],
source : SourceText,
color~ : Bool = true,
) -> String {
@report.render_all(ds, source, color~)
}