feat(natu): ignore imported let bindings
This commit was merged in pull request #122.
This commit is contained in:
@@ -199,6 +199,24 @@ in
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn natu_accepts_single_use_import_binding() -> googletest::Result<()> {
|
||||
let report = natu::future_sight(vec![SourceFile {
|
||||
path: PathBuf::from("testdata/import_binding.nix"),
|
||||
source: r#"
|
||||
let
|
||||
imported = import ./module.nix { };
|
||||
in
|
||||
imported
|
||||
"#
|
||||
.into(),
|
||||
}])
|
||||
.or_fail()?;
|
||||
|
||||
expect_that!(report.is_clean(), is_true());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[gtest]
|
||||
fn natu_reports_single_use_binding() -> googletest::Result<()> {
|
||||
let report = natu::future_sight(vec![SourceFile {
|
||||
|
||||
@@ -38,7 +38,8 @@ fn is_single_use(graph: &ScopeGraph, let_scope: &LetScope, binding: &Binding) ->
|
||||
.filter(|reference| graph.resolve(**reference).contains(&binding.declaration))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self_references == 0
|
||||
!binding.is_import
|
||||
&& self_references == 0
|
||||
&& external_references.len() == 1
|
||||
&& (binding.is_lambda
|
||||
|| !graph.crosses_lambda_scope(*external_references[0], binding.declaration))
|
||||
|
||||
@@ -69,6 +69,7 @@ impl ScopeGraph {
|
||||
declaration: self.add_declaration(&binding.key.name, scope),
|
||||
name: binding.key.name.clone(),
|
||||
references: Vec::new(),
|
||||
is_import: is_import(&binding.value),
|
||||
is_lambda: matches!(binding.value, ast::Expr::Lambda { .. }),
|
||||
range: binding.range,
|
||||
})
|
||||
@@ -191,6 +192,28 @@ impl ScopeGraph {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_import(expr: &ast::Expr) -> bool {
|
||||
match unwrap_expr(expr) {
|
||||
ast::Expr::Apply(application) => is_import_callee(&application.lambda),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_import_callee(expr: &ast::Expr) -> bool {
|
||||
match unwrap_expr(expr) {
|
||||
ast::Expr::Apply(application) => is_import_callee(&application.lambda),
|
||||
ast::Expr::Ident(ident) => ident.name == "import",
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrap_expr(expr: &ast::Expr) -> &ast::Expr {
|
||||
match expr {
|
||||
ast::Expr::Other(expressions) if expressions.len() == 1 => unwrap_expr(&expressions[0]),
|
||||
_ => expr,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Node {
|
||||
Scope(ScopeKind),
|
||||
@@ -237,6 +260,7 @@ pub(crate) struct Binding {
|
||||
pub(crate) declaration: NodeId,
|
||||
pub(crate) name: String,
|
||||
pub(crate) references: Vec<NodeId>,
|
||||
pub(crate) is_import: bool,
|
||||
pub(crate) is_lambda: bool,
|
||||
pub(crate) range: ast::SourceRange,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user