Skip to content

Commit a02626a

Browse files
authored
Never flag _ as an unknown identifier (#804)
tree-sitter parses this as an `identifier` node to keep things simple in the grammar, rather than parsing it as something like a `pipe_placeholder` within a pipe scope, which would be tough to do right. So we have to adapt to that here and always avoid flagging `_` as an unknown symbol.
1 parent 3e41b3e commit a02626a

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

crates/ark/src/lsp/diagnostics.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pub(crate) fn generate_diagnostics(doc: Document, state: WorldState) -> Vec<Diag
131131
_ => {},
132132
});
133133

134+
// Add per-environment session symbols
134135
for scope in state.console_scopes.iter() {
135136
for name in scope.iter() {
136137
if is_symbol_valid(name.as_str()) {
@@ -142,6 +143,10 @@ pub(crate) fn generate_diagnostics(doc: Document, state: WorldState) -> Vec<Diag
142143
}
143144
}
144145

146+
// Add `_` pipe placeholder as a "known" session symbol so we never flag it with
147+
// "symbol not found" when it shows up as an `identifier` node
148+
context.session_symbols.insert(String::from("_"));
149+
145150
for pkg in state.installed_packages.iter() {
146151
context.installed_packages.insert(pkg.clone());
147152
}
@@ -1423,4 +1428,43 @@ foo
14231428
);
14241429
})
14251430
}
1431+
1432+
#[test]
1433+
fn test_no_symbol_diagnostics_for_native_pipe_placeholder() {
1434+
r_task(|| {
1435+
// https://github.com/posit-dev/positron/issues/4102
1436+
let code = "
1437+
x <- list(a = 1)
1438+
x |> _$a[1]
1439+
";
1440+
let document = Document::new(code, None);
1441+
assert_eq!(
1442+
generate_diagnostics(document.clone(), DEFAULT_STATE.clone()).len(),
1443+
0
1444+
);
1445+
1446+
// Imagine this is a data.table
1447+
// https://github.com/posit-dev/positron/issues/3749
1448+
let code = "
1449+
data <- data.frame(a = 1)
1450+
data |> _[1]
1451+
";
1452+
let document = Document::new(code, None);
1453+
assert_eq!(
1454+
generate_diagnostics(document.clone(), DEFAULT_STATE.clone()).len(),
1455+
0
1456+
);
1457+
1458+
// We technically disable diagnostics for this symbol everywhere, even outside
1459+
// of pipe scope, which is probably fine
1460+
let code = "
1461+
_
1462+
";
1463+
let document = Document::new(code, None);
1464+
assert_eq!(
1465+
generate_diagnostics(document.clone(), DEFAULT_STATE.clone()).len(),
1466+
0
1467+
);
1468+
})
1469+
}
14261470
}

0 commit comments

Comments
 (0)