use super::super::ReadabilityContext;
use super::super::walk::{BlockKind, ScopedAstRewritePass, rewrite_module_scoped};
use super::collective::try_wrap_missing_collective_suffix;
use super::facts::{BlockFacts, MissingGlobals, VisibleGlobals};
use super::insert::insert_missing_global_decls;
use super::merge::merge_seed_global_runs;
use crate::ast::common::{AstBlock, AstDialectVersion, AstModule};
pub(in crate::ast::readability) fn apply(module: &mut AstModule, context: ReadabilityContext) -> bool {
if !context.target.caps.global_decl {
return false;
}
let mut pass = GlobalDeclPrettyPass {
infer_missing: context.target.version != AstDialectVersion::Lua55,
};
rewrite_module_scoped(module, &VisibleGlobals::default(), &mut pass)
}
struct GlobalDeclPrettyPass {
infer_missing: bool,
}
impl ScopedAstRewritePass for GlobalDeclPrettyPass {
type Scope = VisibleGlobals;
fn enter_block(
&mut self,
block: &mut AstBlock,
kind: BlockKind,
outer_declared: &Self::Scope,
) -> (bool, Self::Scope) {
let mut changed = merge_seed_global_runs(block);
let facts = BlockFacts::collect(block);
let mut missing = if self.infer_missing
|| facts.has_explicit_globals()
|| outer_declared.has_explicit_gate()
{
facts.infer_missing(outer_declared)
} else {
MissingGlobals::default()
};
if !missing.is_empty()
&& !self.infer_missing
&& !facts.has_explicit_globals()
&& try_wrap_missing_collective_suffix(block, kind, &missing)
{
missing = MissingGlobals::default();
changed = true;
}
if !missing.is_empty() {
insert_missing_global_decls(block, &missing);
changed = true;
}
let visible = facts.visible_globals(outer_declared, &missing);
(changed, visible)
}
}