Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,46 @@ mod tests {
.run();
}

#[test]
fn shadowed_parameter_default_uses_global_variable() {
Test::new(indoc! {
"
a := 'default a'

b a=a:
echo {{ a }}
"
})
.run();
}

#[test]
fn cross_parameter_default_uses_global_variable() {
Test::new(indoc! {
"
a := 'foo'

foo a b=a:
echo {{ a }} {{ b }}
"
})
.run();
}

#[test]
fn parenthesized_expression_default_uses_global_variable() {
Test::new(indoc! {
"
foo := 'foo'
bar := 'bar'

recipe x=(foo + bar):
echo {{ x }}
"
})
.run();
}

#[test]
fn variables_used_in_dependency_args() {
Test::new(indoc! {
Expand Down
102 changes: 100 additions & 2 deletions src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ impl<'a> Resolver<'a> {
.get_node_text(&recipe_node.find("recipe_header > identifier")?),
);

if let Some(recipe) = recipe {
let in_parameter_default = identifier.get_parent("parameter").is_some();

if let Some(recipe) = recipe
&& !in_parameter_default
{
for param in &recipe.parameters {
if param.name == identifier_name {
return Some(lsp::Location {
Expand Down Expand Up @@ -187,7 +191,9 @@ impl<'a> Resolver<'a> {
.get_node_text(&recipe_node.find("recipe_header > identifier")?),
);

if let Some(recipe) = recipe {
let in_parameter_default = identifier.get_parent("parameter").is_some();

if !in_parameter_default && let Some(recipe) = recipe {
for parameter in recipe.parameters {
if parameter.name == text {
return Some(lsp::Hover {
Expand Down Expand Up @@ -324,6 +330,10 @@ impl<'a> Resolver<'a> {
return false;
}

if candidate.get_parent("parameter").is_some() {
return true;
}

let candidate_recipe = self.document.find_recipe(
&candidate_parent
.get_parent("recipe")
Expand Down Expand Up @@ -738,6 +748,94 @@ mod tests {
);
}

#[test]
fn resolve_shadowed_parameter_default_references() {
let document = Document::from(indoc! {
"
a := 'foo'

b a=a:
echo {{ a }}
"
});

let resolver = Resolver::new(&document);

let root = document.tree.as_ref().unwrap().root_node();

let identifier = root.find("assignment > identifier").unwrap();

let references = resolver.resolve_identifier_references(&identifier);

assert_eq!(references.len(), 2);

let ranges = references
.iter()
.map(|reference| reference.range)
.collect::<Vec<_>>();

assert_eq!(
ranges,
vec![
lsp::Range {
start: lsp::Position {
line: 0,
character: 0,
},
end: lsp::Position {
line: 0,
character: 1,
},
},
lsp::Range {
start: lsp::Position {
line: 2,
character: 4,
},
end: lsp::Position {
line: 2,
character: 5,
},
},
]
);
}

#[test]
fn resolve_shadowed_parameter_default_definition() {
let document = Document::from(indoc! {
"
a := 'foo'

b a=a:
echo {{ a }}
"
});

let resolver = Resolver::new(&document);

let root = document.tree.as_ref().unwrap().root_node();

let identifier = root.find("parameter > value > identifier").unwrap();

let definition =
resolver.resolve_identifier_definition(&identifier).unwrap();

assert_eq!(
definition.range,
lsp::Range {
start: lsp::Position {
line: 0,
character: 0,
},
end: lsp::Position {
line: 1,
character: 0,
},
}
);
}

#[test]
fn resolve_dependency_references() {
let document = Document::from(indoc! {
Expand Down
17 changes: 10 additions & 7 deletions src/rule_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,16 @@ impl IdentifierAnalysis {
.or_default()
.insert(identifier_name.clone());

if recipe_parameters
.get(&recipe.name.value)
.is_some_and(|parameters| {
parameters
.iter()
.any(|parameter| parameter.name == identifier_name)
})
let in_parameter_default = identifier.get_parent("parameter").is_some();

if !in_parameter_default
&& recipe_parameters
.get(&recipe.name.value)
.is_some_and(|parameters| {
parameters
.iter()
.any(|parameter| parameter.name == identifier_name)
})
{
return;
}
Expand Down
Loading