// Portions adapted from google/go-jsonnet v0.21.0 (Apache-2.0).
// https://github.com/google/go-jsonnet/tree/67968688d9952f50662e979fab1bef889d0d3e57
// Source: internal/parser/context.go
// Copyright 2017 Google Inc. All rights reserved.
// Modifications: Adapted child traversal to MoonBit AST forms and analysis-only lowering.
// License and retained attribution: LICENSE and NOTICE at the module root.
///|
// Child traversal for lint analysis. Direct children follow the fixed reference's
// desugared eager edges; thunks, functions, locals and lowered std calls stop it.
fn lint_children(e : Expr, direct? : Bool = false) -> Array[Expr] {
let out = []
let optional = fn(x : Expr?) { if x is Some(x) { out.push(x) } }
match e.kind {
Local(bs, body) =>
if !direct {
for { value: x, .. } in bs {
out.push(x)
}
out.push(body)
}
Func(ps, body) =>
if !direct {
for { default_value: x, .. } in ps {
optional(x)
}
out.push(body)
}
Call(f, args, _) => {
out.push(f)
if !direct {
for (_, x) in args {
out.push(x)
}
}
}
If(a, b, c) => {
out.push(a)
out.push(b)
out.push(c)
}
Binary("%" | "in", a, b) =>
if !direct {
out.push(a)
out.push(b)
}
Binary(_, a, b) | Index(a, b) => {
out.push(a)
out.push(b)
}
Unary(_, a) | Fail(a) => out.push(a)
Arr(xs) => if !direct { out.append(xs) }
Obj(fs, bs, _, _) => {
for f in fs {
out.push(f.key)
}
if !direct {
for { value: x, .. } in bs {
out.push(x)
}
for f in fs {
out.push(f.value)
}
}
}
Assert(a, b, c) => {
out.push(a)
optional(b)
out.push(c)
}
Slice(a, b, c, d) =>
if !direct {
out.push(a)
optional(b)
optional(c)
optional(d)
}
ArrayComp(body, cs) =>
if !direct {
out.push(body)
for c in cs {
match c {
For(_, x) | When(x) => out.push(x)
}
}
}
ObjectComp(key, body, cs, bs) =>
if !direct {
out.push(key)
out.push(body)
for { value: x, .. } in bs {
out.push(x)
}
for c in cs {
match c {
For(_, x) | When(x) => out.push(x)
}
}
}
_ => ()
}
out
}