Merge pull request #345 from nix-community/johannes

Pesto: handle callPackage and makeOverridable edge cases
This commit is contained in:
mergify[bot] 2024-09-19 09:31:06 +00:00 committed by GitHub
commit e28d5ce381
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 119 additions and 24 deletions

View File

@ -19,3 +19,15 @@ pesto --file "attrsets.nix" --line "11" --column "3"
"countApplied": 3
}
```
## Contribute
Generating test dataset
`nix build .#pasta -L`
Which can the be passed
`cargo run -- --pos-file result --format json ./out.json`
It is recommended to remove all unneeded entries and operate on minimal list that contains only one entry.

View File

@ -51,33 +51,61 @@ pub fn get_src(path: &PathBuf) -> String {
exit(1);
}
/// Returns the node path
/// Returns rnix::SyntaxKind::NODE_PATH
pub fn get_call_package_file(node: Option<&SyntaxNode>) -> Option<SyntaxNode> {
if let Some(node) = node {
match node.kind() {
rnix::SyntaxKind::NODE_ATTRPATH_VALUE => {
get_call_package_file(node.last_child().as_ref())
for ev in node.preorder() {
let res = match ev {
WalkEvent::Enter(node) => match node.kind() {
rnix::SyntaxKind::NODE_ATTRPATH_VALUE => {
get_call_package_file(node.last_child().as_ref())
}
rnix::SyntaxKind::NODE_APPLY => {
let maybe_path = filter_path_from_apply(&node);
match maybe_path.as_ref().map(|n| n.kind()) {
Some(rnix::SyntaxKind::NODE_PATH) => maybe_path.clone(),
_ => {
// callPackage ./path/file.nix {}
// Maybe the path is a dynamic expression which is non-trivial to resolve?
println!("Could not find path in apply {:?}", &node);
None
}
}
}
_ => None,
},
_ => None,
};
if let Some(res) = res {
return Some(res);
}
rnix::SyntaxKind::NODE_PATH => Some(node.clone()),
rnix::SyntaxKind::NODE_APPLY => match node.first_child().map(|n| n.kind()) {
Some(rnix::SyntaxKind::NODE_APPLY) => {
get_call_package_file(node.first_child().as_ref())
}
_ => get_call_package_file(node.last_child().as_ref()),
},
_ => {
println!(
"Unhandled node when trying to unpack callPackage expression: {:?}",
node.kind()
);
None
} // n => get_call_package_file(node.last_child().as_ref()),
}
} else {
None
}
None
}
fn filter_path_from_apply(apply: &SyntaxNode) -> Option<SyntaxNode> {
for ev in apply.preorder() {
let res = match ev {
WalkEvent::Enter(node) => match node.kind() {
rnix::SyntaxKind::NODE_IDENT => {
// If the first child is callPackage.
// Assume CallPackage takes a second argument, which is the next node.
if node.text().to_string() == "callPackage" {
return node.next_sibling();
}
None
}
_ => None,
},
_ => None,
};
if let Some(res) = res {
return res;
}
}
None
}
/// Goes up the tree to find the parent node that matches the predicate,
/// checks starting with the current node
/// Stops when the limit is reached
@ -301,19 +329,30 @@ pub fn seek_file_position(path: &PathBuf, text_pos: &TextSize) -> Option<FilePos
// (( x: ... )) -> x: ...
// Returns the lambda node, if one exists
// Aborts if the node is not a lambda
// Returns rnix::SyntaxKind::NODE_LAMBDA
fn unpack_lambda(node: &SyntaxNode) -> Option<SyntaxNode> {
for ev in node.preorder() {
let res = match ev {
WalkEvent::Enter(node) => {
match node.kind() {
// The top level callpackage lambda
rnix::SyntaxKind::NODE_PAREN => None,
rnix::SyntaxKind::NODE_LAMBDA => Some(node),
rnix::SyntaxKind::NODE_APPLY => node
.first_child()
.as_ref()
.map(|n| unpack_lambda(n))
.flatten(),
rnix::SyntaxKind::NODE_PAREN => None,
rnix::SyntaxKind::NODE_SELECT => None,
rnix::SyntaxKind::NODE_IDENT => None,
rnix::SyntaxKind::NODE_ATTRPATH => None,
rnix::SyntaxKind::NODE_ATTR_SET => None,
rnix::SyntaxKind::NODE_IF_ELSE => None,
_ => {
println!(
"Unexpected node kind: {:?}. Expected Parenthesis '(x: ...)' or Lambda 'x: ... '",
node.kind()
);
"Unexpected node kind: {:?}. Expected Parenthesis '(x: ...)' or Lambda 'x: ... '",
node.kind()
);
exit(1);
}
}

View File

@ -1,4 +1,48 @@
[
{
"docs": {
"attr": {
"position": {
"column": 3,
"file": "/nix/store/sv1ix2lrwxbflx43b1pqbpj5y1fm5frk-nixpkgs-migrated/pkgs/top-level/all-packages.nix",
"line": 937
}
},
"lambda": {
"countApplied": 1,
"isFunctor": true,
"isPrimop": false,
"position": {
"column": 17,
"file": "/nix/store/sv1ix2lrwxbflx43b1pqbpj5y1fm5frk-nixpkgs-migrated/lib/customisation.nix",
"line": 136
}
}
},
"path": ["pkgs", "fetchgit"]
},
{
"docs": {
"attr": {
"position": {
"column": 3,
"file": "/nix/store/sv1ix2lrwxbflx43b1pqbpj5y1fm5frk-nixpkgs-migrated/pkgs/top-level/all-packages.nix",
"line": 922
}
},
"lambda": {
"countApplied": 1,
"isFunctor": true,
"isPrimop": false,
"position": {
"column": 17,
"file": "/nix/store/sv1ix2lrwxbflx43b1pqbpj5y1fm5frk-nixpkgs-migrated/lib/customisation.nix",
"line": 136
}
}
},
"path": ["pkgs", "fetchcvs"]
},
{
"docs": {
"attr": {