Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-db/src/active_parameter.rs')
-rw-r--r--crates/ide-db/src/active_parameter.rs47
1 files changed, 39 insertions, 8 deletions
diff --git a/crates/ide-db/src/active_parameter.rs b/crates/ide-db/src/active_parameter.rs
index 11808fed3b..7b5723f37f 100644
--- a/crates/ide-db/src/active_parameter.rs
+++ b/crates/ide-db/src/active_parameter.rs
@@ -3,9 +3,11 @@
use either::Either;
use hir::{InFile, Semantics, Type};
use parser::T;
+use span::TextSize;
use syntax::{
+ AstNode, NodeOrToken, SyntaxToken,
ast::{self, AstChildren, HasArgList, HasAttrs, HasName},
- match_ast, AstNode, NodeOrToken, SyntaxToken,
+ match_ast,
};
use crate::RootDatabase;
@@ -20,7 +22,24 @@ impl ActiveParameter {
/// Returns information about the call argument this token is part of.
pub fn at_token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Self> {
let (signature, active_parameter) = callable_for_token(sema, token)?;
+ Self::from_signature_and_active_parameter(sema, signature, active_parameter)
+ }
+ /// Returns information about the call argument this token is part of.
+ pub fn at_arg(
+ sema: &Semantics<'_, RootDatabase>,
+ list: ast::ArgList,
+ at: TextSize,
+ ) -> Option<Self> {
+ let (signature, active_parameter) = callable_for_arg_list(sema, list, at)?;
+ Self::from_signature_and_active_parameter(sema, signature, active_parameter)
+ }
+
+ fn from_signature_and_active_parameter(
+ sema: &Semantics<'_, RootDatabase>,
+ signature: hir::Callable,
+ active_parameter: Option<usize>,
+ ) -> Option<Self> {
let idx = active_parameter?;
let mut params = signature.params();
if idx >= params.len() {
@@ -48,20 +67,32 @@ pub fn callable_for_token(
sema: &Semantics<'_, RootDatabase>,
token: SyntaxToken,
) -> Option<(hir::Callable, Option<usize>)> {
+ let offset = token.text_range().start();
// Find the calling expression and its NameRef
let parent = token.parent()?;
- let calling_node = parent.ancestors().filter_map(ast::CallableExpr::cast).find(|it| {
- it.arg_list()
- .is_some_and(|it| it.syntax().text_range().contains(token.text_range().start()))
- })?;
+ let calling_node = parent
+ .ancestors()
+ .filter_map(ast::CallableExpr::cast)
+ .find(|it| it.arg_list().is_some_and(|it| it.syntax().text_range().contains(offset)))?;
+
+ callable_for_node(sema, &calling_node, offset)
+}
- callable_for_node(sema, &calling_node, &token)
+/// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable.
+pub fn callable_for_arg_list(
+ sema: &Semantics<'_, RootDatabase>,
+ arg_list: ast::ArgList,
+ at: TextSize,
+) -> Option<(hir::Callable, Option<usize>)> {
+ debug_assert!(arg_list.syntax().text_range().contains(at));
+ let callable = arg_list.syntax().parent().and_then(ast::CallableExpr::cast)?;
+ callable_for_node(sema, &callable, at)
}
pub fn callable_for_node(
sema: &Semantics<'_, RootDatabase>,
calling_node: &ast::CallableExpr,
- token: &SyntaxToken,
+ offset: TextSize,
) -> Option<(hir::Callable, Option<usize>)> {
let callable = match calling_node {
ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?),
@@ -73,7 +104,7 @@ pub fn callable_for_node(
.children_with_tokens()
.filter_map(NodeOrToken::into_token)
.filter(|t| t.kind() == T![,])
- .take_while(|t| t.text_range().start() <= token.text_range().start())
+ .take_while(|t| t.text_range().start() <= offset)
.count()
});
Some((callable, active_param))