///|
/// Metadata is a spelling hint, never an exact request or a trust decision.
/// Duplicate fields, invalid spans and ambiguous hints are ignored and retained.
fn hint_field(value : @ion.IonValue, name : String) -> @ion.IonValue? {
guard value.kind() is Struct(fields) else { return None }
let matches = fields.filter(f => f.name().text() == Some(name))
if matches.length() == 1 {
Some(matches[0].value())
} else {
None
}
}
///|
fn hint_text(value : @ion.IonValue, name : String) -> String? {
match hint_field(value, name) {
Some(v) =>
match v.kind() {
String(text) => Some(text)
_ => None
}
None => None
}
}
///|
fn hint_span(value : @ion.IonValue) -> @diagnostics.Span? {
fn coordinate(value : @ion.IonValue, name : String) -> Int32? {
guard hint_field(value, name) is Some(v) else { return None }
guard v.kind() is Int(n) else { return None }
let text = n.to_string()
let result = @strconv.parse_int(text) catch { _ => return None }
if result >= 0 {
Some(result)
} else {
None
}
}
guard coordinate(value, "start_line") is Some(start_line) else { return None }
guard coordinate(value, "start_column") is Some(start_column) else {
return None
}
guard coordinate(value, "end_line") is Some(end_line) else { return None }
guard coordinate(value, "end_column") is Some(end_column) else { return None }
if end_line < start_line ||
(end_line == start_line && end_column < start_column) {
return None
}
Some({ start_line, start_column, end_line, end_column, })
}
///|
fn moonbit_origins(input : Input) -> Bool {
input.provenance.any(p => {
p.annotations().any(a => a.text() == Some("morphir_moonbit_frontend")) &&
hint_text(p, "unit_id") == Some(input.unit_id) &&
(
hint_text(p, "language") == Some("moonbit") ||
hint_text(p, "frontend") == Some("moonbit-model-bool-v1")
)
})
}
///|
fn declaration_hint(
plan : TargetNames,
owner : String,
) -> (String?, @diagnostics.Span?) {
guard plan.origins.get(owner) is Some(data) else { return (None, None) }
guard hint_field(data, "declaration") is Some(origin) else {
return (None, None)
}
(hint_text(origin, "name"), hint_span(origin))
}