mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
Add fn signature query
This commit is contained in:
parent
e5a6cf8153
commit
98957f4e6f
8 changed files with 86 additions and 7 deletions
|
@ -108,6 +108,7 @@ salsa::database_storage! {
|
||||||
fn impls_in_module() for hir::db::ImplsInModuleQuery;
|
fn impls_in_module() for hir::db::ImplsInModuleQuery;
|
||||||
fn body_hir() for hir::db::BodyHirQuery;
|
fn body_hir() for hir::db::BodyHirQuery;
|
||||||
fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery;
|
fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery;
|
||||||
|
fn fn_signature() for hir::db::FnSignatureQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
|
DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
|
||||||
SourceFileItems, SourceItemId,
|
SourceFileItems, SourceItemId,
|
||||||
query_definitions,
|
query_definitions,
|
||||||
FnScopes,
|
FnSignature, FnScopes,
|
||||||
macros::MacroExpansion,
|
macros::MacroExpansion,
|
||||||
module::{ModuleId, ModuleTree, ModuleSource,
|
module::{ModuleId, ModuleTree, ModuleSource,
|
||||||
nameres::{ItemMap, InputModuleItems}},
|
nameres::{ItemMap, InputModuleItems}},
|
||||||
|
@ -103,6 +103,11 @@ pub trait HirDatabase: SyntaxDatabase
|
||||||
type BodySyntaxMappingQuery;
|
type BodySyntaxMappingQuery;
|
||||||
use fn crate::expr::body_syntax_mapping;
|
use fn crate::expr::body_syntax_mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fn_signature(def_id: DefId) -> Arc<FnSignature> {
|
||||||
|
type FnSignatureQuery;
|
||||||
|
use fn crate::function::fn_signature;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ra_syntax::{
|
||||||
ast::{self, AstNode, DocCommentsOwner, NameOwner},
|
ast::{self, AstNode, DocCommentsOwner, NameOwner},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}};
|
use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}, type_ref::{TypeRef, Mutability}, Name};
|
||||||
|
|
||||||
pub use self::scope::{FnScopes, ScopesWithSyntaxMapping};
|
pub use self::scope::{FnScopes, ScopesWithSyntaxMapping};
|
||||||
|
|
||||||
|
@ -53,6 +53,10 @@ impl Function {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
|
||||||
|
db.fn_signature(self.def_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
|
pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
|
||||||
let syntax = self.syntax(db);
|
let syntax = self.syntax(db);
|
||||||
FnSignatureInfo::new(syntax.borrowed())
|
FnSignatureInfo::new(syntax.borrowed())
|
||||||
|
@ -76,6 +80,60 @@ impl Function {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The declared signature of a function.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct FnSignature {
|
||||||
|
args: Vec<TypeRef>,
|
||||||
|
ret_type: TypeRef,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FnSignature {
|
||||||
|
pub fn args(&self) -> &[TypeRef] {
|
||||||
|
&self.args
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ret_type(&self) -> &TypeRef {
|
||||||
|
&self.ret_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
|
||||||
|
let func = Function::new(def_id);
|
||||||
|
let syntax = func.syntax(db);
|
||||||
|
let node = syntax.borrowed();
|
||||||
|
let mut args = Vec::new();
|
||||||
|
if let Some(param_list) = node.param_list() {
|
||||||
|
if let Some(self_param) = param_list.self_param() {
|
||||||
|
let self_type = if let Some(type_ref) = self_param.type_ref() {
|
||||||
|
TypeRef::from_ast(type_ref)
|
||||||
|
} else {
|
||||||
|
let self_type = TypeRef::Path(Name::self_type().into());
|
||||||
|
match self_param.flavor() {
|
||||||
|
ast::SelfParamFlavor::Owned => self_type,
|
||||||
|
ast::SelfParamFlavor::Ref => {
|
||||||
|
TypeRef::Reference(Box::new(self_type), Mutability::Shared)
|
||||||
|
}
|
||||||
|
ast::SelfParamFlavor::MutRef => {
|
||||||
|
TypeRef::Reference(Box::new(self_type), Mutability::Mut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
args.push(self_type);
|
||||||
|
}
|
||||||
|
for param in param_list.params() {
|
||||||
|
let type_ref = TypeRef::from_ast_opt(param.type_ref());
|
||||||
|
args.push(type_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) {
|
||||||
|
TypeRef::from_ast(type_ref)
|
||||||
|
} else {
|
||||||
|
TypeRef::unit()
|
||||||
|
};
|
||||||
|
let sig = FnSignature { args, ret_type };
|
||||||
|
Arc::new(sig)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FnSignatureInfo {
|
pub struct FnSignatureInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub use self::{
|
||||||
ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc},
|
ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc},
|
||||||
macros::{MacroDef, MacroInput, MacroExpansion},
|
macros::{MacroDef, MacroInput, MacroExpansion},
|
||||||
module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution},
|
module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution},
|
||||||
function::{Function, FnScopes, ScopesWithSyntaxMapping},
|
function::{Function, FnSignature, FnScopes, ScopesWithSyntaxMapping},
|
||||||
adt::{Struct, Enum},
|
adt::{Struct, Enum},
|
||||||
ty::Ty,
|
ty::Ty,
|
||||||
impl_block::{ImplBlock, ImplItem},
|
impl_block::{ImplBlock, ImplItem},
|
||||||
|
|
|
@ -210,6 +210,7 @@ salsa::database_storage! {
|
||||||
fn impls_in_module() for db::ImplsInModuleQuery;
|
fn impls_in_module() for db::ImplsInModuleQuery;
|
||||||
fn body_hir() for db::BodyHirQuery;
|
fn body_hir() for db::BodyHirQuery;
|
||||||
fn body_syntax_mapping() for db::BodySyntaxMappingQuery;
|
fn body_syntax_mapping() for db::BodySyntaxMappingQuery;
|
||||||
|
fn fn_signature() for db::FnSignatureQuery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,10 @@ impl Name {
|
||||||
Name::new("self".into())
|
Name::new("self".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn self_type() -> Name {
|
||||||
|
Name::new("Self".into())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn tuple_field_name(idx: usize) -> Name {
|
pub(crate) fn tuple_field_name(idx: usize) -> Name {
|
||||||
Name::new(idx.to_string().into())
|
Name::new(idx.to_string().into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,7 @@ impl Path {
|
||||||
|
|
||||||
/// Converts an `ast::NameRef` into a single-identifier `Path`.
|
/// Converts an `ast::NameRef` into a single-identifier `Path`.
|
||||||
pub fn from_name_ref(name_ref: ast::NameRef) -> Path {
|
pub fn from_name_ref(name_ref: ast::NameRef) -> Path {
|
||||||
Path {
|
name_ref.as_name().into()
|
||||||
kind: PathKind::Plain,
|
|
||||||
segments: vec![name_ref.as_name()],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `true` is this path is a single identifier, like `foo`
|
/// `true` is this path is a single identifier, like `foo`
|
||||||
|
@ -92,6 +89,15 @@ impl Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Name> for Path {
|
||||||
|
fn from(name: Name) -> Path {
|
||||||
|
Path {
|
||||||
|
kind: PathKind::Plain,
|
||||||
|
segments: vec![name],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn expand_use_tree(
|
fn expand_use_tree(
|
||||||
prefix: Option<Path>,
|
prefix: Option<Path>,
|
||||||
tree: ast::UseTree,
|
tree: ast::UseTree,
|
||||||
|
|
|
@ -107,4 +107,8 @@ impl TypeRef {
|
||||||
TypeRef::Error
|
TypeRef::Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unit() -> TypeRef {
|
||||||
|
TypeRef::Tuple(Vec::new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue