Loading...
Loading...
Refactor MoonBit code to be idiomatic: shrink public APIs, convert functions to methods, use pattern matching with views, add loop invariants, and ensure test coverage without regressions. Use when updating MoonBit packages or refactoring MoonBit APIs, modules, or tests.
npx skill4agent add moonbitlang/moonbit-agent-guide moonbit-refactoringmoon docmoon ide find-referencesmoon checkmoon testAAB// In package B
using @A { ... } // re-export A's APIsmoon checkmoon ide find-references <symbol>f@B.fusepubinternal/pubinternal/..// Before
fn reader_next(r : Reader) -> Char? { ... }
let ch = reader_next(r)
// After
#as_free_fn(reader_next, deprecated="Use Reader::next instead")
fn Reader::next(self : Reader) -> Char? { ... }
let ch = r.next()#as_free_fn(old_name, ...)old_namebuf..write_string("#\\")..write_char(ch)@pkg.fnusinglet n = @parser.parse_number(token)// Pattern matching - annotate the value being matched
let tree : @pkga.Tree = ...
match tree {
Leaf(x) => x
Node(left~, x, right~) => left.sum() + x + right.sum()
}
// Nested constructors - only outer needs full path
let x = @pkga.Tree::Node(left=Leaf(1), x=2, right=Leaf(3))
// Return type provides context
fn make_tree() -> @pkga.Tree {
Node(left=Leaf(1), x=2, right=Leaf(3))
}
// Collections - type annotation on the array
let trees : Array[@pkga.Tree] = [Leaf(1), Node(left=Leaf(2), x=3, right=Leaf(4))]..Array[Char]StringStringViewUInt16for ch in s match gen_results.get(0) {
Some(value) => Iter::singleton(value)
None => Iter::empty()
} match gen_results {
[value, ..] => Iter::singleton(value)
[] => Iter::empty()
}match items {
[] => ()
[head, ..tail] => handle(head, tail)
[..prefix, mid, ..suffix] => handle_mid(prefix, mid, suffix)
}match s {
"" => ()
[.."let", ..rest] => handle_let(rest)
_ => ()
}CharUInt16IntStringUInt16test {
let a_int : Int = 'b'
if (a_int is 'a'..<'z') { () } else { () }
let a_u16 : UInt16 = 'b'
if (a_u16 is 'a'..<'z') { () } else { () }
let a_char : Char = 'b'
if (a_char is 'a'..<'z') { () } else { () }
}isisifguardmatch token {
Some(Ident([.."@", ..rest])) if process(rest) is Some(x) => handle_at(rest)
Some(Ident(name)) => handle_ident(name)
None => ()
}// Before
let mut a = 1
let mut b = 2
for i = 0 {
if i >= n {
break
}
a = a + b
b = b + a
continue i + 1
}for i = 0, a = 1, b = 2 {
if i >= n {
break a
}
continue i + 1, b, b + a
}for _ in 0..<n; a = 1, b = 2 {
continue b, a + b
} nobreak {
a
}for i in start..<end { ... }for i in start..<=end { ... }for i in large>..smallfor i in large>=..smallfor// Before
for i = 0; i < len; {
items.push(fill)
continue i + 1
}
// After
for i in 0..<len {
items.push(fill)
}for x in xsfor i = 0, acc = 0; i < xs.length(); {
acc = acc + xs[i]
i = i + 1
} else { acc }
where {
invariant: 0 <= i <= xs.length(),
reasoning: (
#| ... rigorous explanation ...
#| ...
)
}*_test.mbt*.mbt.mdmbt checkmoon check && moon test///|
/// Return the last element of a non-empty array.
///
/// # Example
/// ```mbt check
/// test {
/// inspect(last([1, 2, 3]), content="3")
/// }
/// ```
pub fn last(xs : Array[Int]) -> Int { ... }moon coverage analyze -- -f summary
moon coverage analyze -- -f caret -F path/to/file.mbtmoon doc "<query>"
moon ide outline <dir|file>
moon ide find-references <symbol>
moon ide peek-def <symbol>
moon ide rename <symbol> -new-name <new_name>
moon check
moon test
moon infopackage_bpackage_apackage_busing @package_a { a, type B }moon ide find-references <symbol>aB@package_a.a@package_a.Busingmoon check