///|
priv struct LabelNames {
mut active : Array[(Int, String)]
by_depth : Array[String]
generator : NameGenerator
}
///|
fn LabelNames::new(alphabet : NameAlphabet) -> LabelNames {
{
active: [],
by_depth: [],
generator: NameGenerator::new(alphabet, keywords),
}
}
///|
fn Printer::label_reference(
self : Printer,
name : Int,
start : Int,
end : Int,
) -> Unit {
for index = self.labels.active.length() - 1 {
guard index >= 0 else {
self.span(start, end, true)
break
}
let (original, renamed) = self.labels.active[index]
guard original == name else { continue index - 1 }
self.text(renamed, true)
break
}
}
///|
fn Printer::label_name(self : Printer) -> String {
let depth = self.labels.active.length()
if depth == self.labels.by_depth.length() {
self.labels.by_depth.push(self.labels.generator.next_name())
}
self.labels.by_depth[depth]
}
///|
/// Functions and class static blocks have independent label namespaces.
fn Printer::isolated_block(self : Printer, id : Int) -> Unit {
let outer = self.labels.active
self.labels.active = []
self.block(id)
self.labels.active = outer
}