1 //! This module provides functionality for querying callable information about a token.
4 use hir::{Semantics, Type};
6 ast::{self, HasArgList, HasName},
10 use crate::RootDatabase;
13 pub struct ActiveParameter {
15 pub pat: Either<ast::SelfParam, ast::Pat>,
18 impl ActiveParameter {
19 /// Returns information about the call argument this token is part of.
20 pub fn at_token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Self> {
21 let (signature, active_parameter) = callable_for_token(sema, token)?;
23 let idx = active_parameter?;
24 let mut params = signature.params(sema.db);
25 if !(idx < params.len()) {
26 cov_mark::hit!(too_many_arguments);
29 let (pat, ty) = params.swap_remove(idx);
30 pat.map(|pat| ActiveParameter { ty, pat })
33 pub fn ident(&self) -> Option<ast::Name> {
34 self.pat.as_ref().right().and_then(|param| match param {
35 ast::Pat::IdentPat(ident) => ident.name(),
41 /// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable.
42 pub fn callable_for_token(
43 sema: &Semantics<'_, RootDatabase>,
45 ) -> Option<(hir::Callable, Option<usize>)> {
46 // Find the calling expression and its NameRef
47 let parent = token.parent()?;
48 let calling_node = parent.ancestors().filter_map(ast::CallableExpr::cast).find(|it| {
50 .map_or(false, |it| it.syntax().text_range().contains(token.text_range().start()))
53 callable_for_node(sema, &calling_node, &token)
56 pub fn callable_for_node(
57 sema: &Semantics<'_, RootDatabase>,
58 calling_node: &ast::CallableExpr,
60 ) -> Option<(hir::Callable, Option<usize>)> {
61 let callable = match &calling_node {
62 ast::CallableExpr::Call(call) => {
63 let expr = call.expr()?;
64 sema.type_of_expr(&expr)?.adjusted().as_callable(sema.db)
66 ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call),
68 let active_param = if let Some(arg_list) = calling_node.arg_list() {
71 .take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
77 Some((callable, active_param))