Skip to content

Commit 4ea50a3

Browse files
committed
Bail when character.only is supplied
1 parent b9b757e commit 4ea50a3

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

crates/ark/src/lsp/diagnostics.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -822,12 +822,23 @@ fn recurse_call(
822822
}
823823

824824
fn handle_package_attach_call(node: Node, context: &mut DiagnosticContext) -> anyhow::Result<()> {
825-
// Find the first argument (package name). Positionally for now.
826-
let Some(value) = node.arguments_values().nth(0) else {
825+
// Find the first argument (package name). Positionally for now, no attempt
826+
// at argument matching whatsoever.
827+
let Some(package_node) = node.arguments_values().nth(0) else {
827828
return Err(anyhow::anyhow!("Can't unpack attached package argument"));
828829
};
829830

830-
let package_name = value.get_identifier_or_string_text(context.contents)?;
831+
// Just bail if `character.only` is passed, even if it's actually `FALSE`.
832+
// We'll do better when we have a more capable argument inspection
833+
// infrastructure.
834+
if let Some(_) = node
835+
.arguments_names_as_string(context.contents)
836+
.find(|n| n == "character.only")
837+
{
838+
return Ok(());
839+
}
840+
841+
let package_name = package_node.get_identifier_or_string_text(context.contents)?;
831842
let attach_pos = node.end_position();
832843

833844
let package = match insert_package_exports(&package_name, attach_pos, context) {
@@ -1666,8 +1677,26 @@ foo
16661677
bar
16671678
";
16681679
let document = Document::new(code, None);
1669-
let diagnostics = generate_diagnostics(document, state);
1680+
let diagnostics = generate_diagnostics(document, state.clone());
16701681
assert_eq!(diagnostics.len(), 0);
1682+
1683+
// If the library call includes the `character.only` argument, we bail
1684+
let code = r#"
1685+
library(mockpkg, character.only = TRUE)
1686+
foo()
1687+
"#;
1688+
let document = Document::new(code, None);
1689+
let diagnostics = generate_diagnostics(document, state.clone());
1690+
assert_eq!(diagnostics.len(), 1);
1691+
1692+
// Same if passed `FALSE`, we're not trying to be smart (yet)
1693+
let code = r#"
1694+
library(mockpkg, character.only = FALSE)
1695+
foo()
1696+
"#;
1697+
let document = Document::new(code, None);
1698+
let diagnostics = generate_diagnostics(document, state);
1699+
assert_eq!(diagnostics.len(), 1);
16711700
});
16721701
}
16731702

crates/ark/src/lsp/traits/node.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use tree_sitter::Range;
1111
use tree_sitter::TreeCursor;
1212

1313
use crate::lsp::traits::point::PointExt;
14+
use crate::lsp::traits::rope::RopeExt;
1415

1516
fn _dump_impl(cursor: &mut TreeCursor, source: &str, indent: &str, output: &mut String) {
1617
let node = cursor.node();
@@ -95,6 +96,7 @@ pub trait NodeExt: Sized {
9596
fn arguments(&self) -> impl Iterator<Item = (Option<Self>, Option<Self>)>;
9697
fn arguments_values(&self) -> impl Iterator<Item = Self>;
9798
fn arguments_names(&self) -> impl Iterator<Item = Self>;
99+
fn arguments_names_as_string(&self, contents: &ropey::Rope) -> impl Iterator<Item = String>;
98100
}
99101

100102
impl<'tree> NodeExt for Node<'tree> {
@@ -279,6 +281,18 @@ impl<'tree> NodeExt for Node<'tree> {
279281
self.arguments().filter_map(|(name, _value)| name)
280282
}
281283

284+
fn arguments_names_as_string(&self, contents: &ropey::Rope) -> impl Iterator<Item = String> {
285+
self.arguments_names().filter_map(|node| -> Option<String> {
286+
match contents.node_slice(&node) {
287+
Err(err) => {
288+
tracing::error!("Can't convert argument name to text: {err:?}");
289+
None
290+
},
291+
Ok(text) => Some(text.to_string()),
292+
}
293+
})
294+
}
295+
282296
fn arguments_values(&self) -> impl Iterator<Item = Node<'tree>> {
283297
self.arguments().filter_map(|(_name, value)| value)
284298
}

0 commit comments

Comments
 (0)