feat(xatu): add let order rule #88
@@ -36,20 +36,15 @@ pub enum NodeData {
|
||||
pub struct Binding {
|
||||
pub key: Ident,
|
||||
pub value: Expr,
|
||||
pub references: Vec<Ident>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LetBlock {
|
||||
pub bindings: Vec<LetBinding>,
|
||||
pub bindings: Vec<Binding>,
|
||||
pub body_references: Vec<Ident>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LetBinding {
|
||||
pub name: Ident,
|
||||
pub references: Vec<Ident>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Ident {
|
||||
pub name: String,
|
||||
|
||||
@@ -71,7 +71,7 @@ impl TryFrom<rnix::ast::LetIn> for ast::LetBlock {
|
||||
fn try_from(let_block: rnix::ast::LetIn) -> Result<Self, Self::Error> {
|
||||
let bindings = let_block
|
||||
.attrpath_values()
|
||||
.map(ast::LetBinding::try_from)
|
||||
.map(ast::Binding::try_from)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let body_references = let_block.body().ok_or(())?.references();
|
||||
|
||||
@@ -82,26 +82,6 @@ impl TryFrom<rnix::ast::LetIn> for ast::LetBlock {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<rnix::ast::AttrpathValue> for ast::LetBinding {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(binding: rnix::ast::AttrpathValue) -> Result<Self, Self::Error> {
|
||||
let mut attrs = binding.attrpath().ok_or(())?.attrs();
|
||||
let name = match attrs.next().ok_or(())? {
|
||||
Attr::Ident(ident) => ident.into(),
|
||||
_ => return Err(()),
|
||||
};
|
||||
|
||||
if attrs.next().is_some() {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let references = binding.value().ok_or(())?.references();
|
||||
|
||||
Ok(Self { name, references })
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<rnix::ast::AttrpathValue> for ast::Binding {
|
||||
type Error = ();
|
||||
|
||||
@@ -116,9 +96,15 @@ impl TryFrom<rnix::ast::AttrpathValue> for ast::Binding {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let value = binding.value().ok_or(())?.try_into()?;
|
||||
let value_expr = binding.value().ok_or(())?;
|
||||
let references = value_expr.references();
|
||||
let value = value_expr.try_into()?;
|
||||
|
||||
Ok(Self { key, value })
|
||||
Ok(Self {
|
||||
key,
|
||||
value,
|
||||
references,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ fn expected_order(let_block: &ast::LetBlock) -> Option<Vec<String>> {
|
||||
let bindings = let_block
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| (binding.name.name.as_str(), binding))
|
||||
.map(|binding| (binding.key.name.as_str(), binding))
|
||||
.collect::<HashMap<_, _>>();
|
||||
let mut order = Vec::new();
|
||||
let mut permanent_marks = HashSet::new();
|
||||
@@ -59,7 +59,7 @@ fn expected_order(let_block: &ast::LetBlock) -> Option<Vec<String>> {
|
||||
|
||||
fn visit_binding(
|
||||
name: &str,
|
||||
bindings: &HashMap<&str, &ast::LetBinding>,
|
||||
bindings: &HashMap<&str, &ast::Binding>,
|
||||
order: &mut Vec<String>,
|
||||
permanent_marks: &mut HashSet<String>,
|
||||
temporary_marks: &mut HashSet<String>,
|
||||
@@ -98,7 +98,7 @@ fn reachable_actual_order(let_block: &ast::LetBlock, expected_order: &[String])
|
||||
let_block
|
||||
.bindings
|
||||
.iter()
|
||||
.filter(|binding| reachable_names.contains(&binding.name.name))
|
||||
.map(|binding| binding.name.name.clone())
|
||||
.filter(|binding| reachable_names.contains(&binding.key.name))
|
||||
.map(|binding| binding.key.name.clone())
|
||||
.collect()
|
||||
}
|
||||
|
||||
2
src/xatu/testdata/lint_findings.nix
vendored
2
src/xatu/testdata/lint_findings.nix
vendored
@@ -1,5 +1,5 @@
|
||||
let
|
||||
support = "support";
|
||||
support = dependency;
|
||||
primary = support;
|
||||
in {
|
||||
package = package;
|
||||
|
||||
Reference in New Issue
Block a user