mirror of
https://github.com/astro/deadnix.git
synced 2024-11-24 09:12:50 +03:00
scope: add inherits_from() to treat inherit
clauses specially
This commit is contained in:
parent
236876b13f
commit
96a06966bc
@ -159,6 +159,12 @@ fn rec_attrset_shadowed() {
|
||||
assert_eq!(results[0].binding.name.as_str(), "dead");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_inherit_in_let_inherit_alive() {
|
||||
let results = run("let alive = true; in let inherit alive; in alive");
|
||||
assert_eq!(0, results.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn let_inherit_in_rec_attrset_alive() {
|
||||
let results = run("let alive = true; in rec { inherit alive; }");
|
||||
|
32
src/scope.rs
32
src/scope.rs
@ -218,4 +218,36 @@ impl Scope {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the `inherit (var) ...` and `inherit vars` clauses for a
|
||||
/// given `name`.
|
||||
///
|
||||
/// Although a scope may shadow existing variable bindings, it can
|
||||
/// `inherit` bindings from the outer scope.
|
||||
pub fn inherits_from(&self, name: &Ident) -> bool {
|
||||
match self {
|
||||
Scope::LambdaPattern(_, _) | Scope::LambdaArg(_, _) =>
|
||||
false,
|
||||
|
||||
Scope::LetIn(let_in) =>
|
||||
let_in.inherits().any(|inherit|
|
||||
inherit.from()
|
||||
.map(|from|
|
||||
crate::usage::find_usage(name, from.node().clone())
|
||||
).unwrap_or_else(||
|
||||
crate::usage::find_usage(name, inherit.node().clone())
|
||||
)
|
||||
),
|
||||
|
||||
Scope::RecAttrSet(attr_set) =>
|
||||
attr_set.inherits().any(|inherit|
|
||||
inherit.from()
|
||||
.map(|from|
|
||||
crate::usage::find_usage(name, from.node().clone())
|
||||
).unwrap_or_else(||
|
||||
crate::usage::find_usage(name, inherit.node().clone())
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,10 @@ use crate::scope::Scope;
|
||||
/// find out if `name` is used in `node`
|
||||
pub fn find_usage(name: &Ident, node: SyntaxNode<NixLanguage>) -> bool {
|
||||
if let Some(scope) = Scope::new(&node) {
|
||||
if scope.inherits_from(name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for binding in scope.bindings() {
|
||||
if binding.name.as_str() == name.as_str() {
|
||||
// shadowed by a a new child scope that redefines the
|
||||
|
Loading…
Reference in New Issue
Block a user