]> git.lizzy.rs Git - rust.git/commitdiff
Move FunctionData to hir_def
authorAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 22 Nov 2019 14:10:51 +0000 (17:10 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 22 Nov 2019 14:18:04 +0000 (17:18 +0300)
14 files changed:
crates/ra_hir/src/code_model.rs
crates/ra_hir/src/db.rs
crates/ra_hir/src/lib.rs
crates/ra_hir/src/ty/infer.rs
crates/ra_hir/src/ty/lower.rs
crates/ra_hir/src/ty/method_resolution.rs
crates/ra_hir_def/src/db.rs
crates/ra_hir_def/src/function.rs [new file with mode: 0644]
crates/ra_hir_def/src/lib.rs
crates/ra_ide_api/src/call_info.rs
crates/ra_ide_api/src/change.rs
crates/ra_ide_api/src/completion/complete_dot.rs
crates/ra_ide_api/src/completion/complete_path.rs
crates/ra_ide_api/src/completion/presentation.rs

index 72c9b466f7dbca462f890580518ce4a34683da0c..f426f8c9fa8edeace57a5a3b51403649484e8d7a 100644 (file)
@@ -13,7 +13,7 @@
     nameres::per_ns::PerNs,
     resolver::{HasResolver, TypeNs},
     traits::TraitData,
-    type_ref::{Mutability, TypeRef},
+    type_ref::TypeRef,
     ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
     ModuleId, UnionId,
 };
@@ -561,77 +561,6 @@ pub struct Function {
     pub(crate) id: FunctionId,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct FnData {
-    pub(crate) name: Name,
-    pub(crate) params: Vec<TypeRef>,
-    pub(crate) ret_type: TypeRef,
-    /// True if the first param is `self`. This is relevant to decide whether this
-    /// can be called as a method.
-    pub(crate) has_self_param: bool,
-}
-
-impl FnData {
-    pub(crate) fn fn_data_query(
-        db: &(impl DefDatabase + AstDatabase),
-        func: Function,
-    ) -> Arc<FnData> {
-        let src = func.source(db);
-        let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
-        let mut params = Vec::new();
-        let mut has_self_param = false;
-        if let Some(param_list) = src.value.param_list() {
-            if let Some(self_param) = param_list.self_param() {
-                let self_type = if let Some(type_ref) = self_param.ascribed_type() {
-                    TypeRef::from_ast(type_ref)
-                } else {
-                    let self_type = TypeRef::Path(name::SELF_TYPE.into());
-                    match self_param.kind() {
-                        ast::SelfParamKind::Owned => self_type,
-                        ast::SelfParamKind::Ref => {
-                            TypeRef::Reference(Box::new(self_type), Mutability::Shared)
-                        }
-                        ast::SelfParamKind::MutRef => {
-                            TypeRef::Reference(Box::new(self_type), Mutability::Mut)
-                        }
-                    }
-                };
-                params.push(self_type);
-                has_self_param = true;
-            }
-            for param in param_list.params() {
-                let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
-                params.push(type_ref);
-            }
-        }
-        let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
-            TypeRef::from_ast(type_ref)
-        } else {
-            TypeRef::unit()
-        };
-
-        let sig = FnData { name, params, ret_type, has_self_param };
-        Arc::new(sig)
-    }
-    pub fn name(&self) -> &Name {
-        &self.name
-    }
-
-    pub fn params(&self) -> &[TypeRef] {
-        &self.params
-    }
-
-    pub fn ret_type(&self) -> &TypeRef {
-        &self.ret_type
-    }
-
-    /// True if the first arg is `self`. This is relevant to decide whether this
-    /// can be called as a method.
-    pub fn has_self_param(&self) -> bool {
-        self.has_self_param
-    }
-}
-
 impl Function {
     pub fn module(self, db: &impl DefDatabase) -> Module {
         self.id.lookup(db).module(db).into()
@@ -642,7 +571,15 @@ pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
     }
 
     pub fn name(self, db: &impl HirDatabase) -> Name {
-        self.data(db).name.clone()
+        db.function_data(self.id).name.clone()
+    }
+
+    pub fn has_self_param(self, db: &impl HirDatabase) -> bool {
+        db.function_data(self.id).has_self_param
+    }
+
+    pub fn params(self, db: &impl HirDatabase) -> Vec<TypeRef> {
+        db.function_data(self.id).params.clone()
     }
 
     pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
@@ -657,10 +594,6 @@ pub fn ty(self, db: &impl HirDatabase) -> Ty {
         db.type_for_def(self.into(), Namespace::Values)
     }
 
-    pub fn data(self, db: &impl HirDatabase) -> Arc<FnData> {
-        db.fn_data(self)
-    }
-
     pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
         db.infer(self.into())
     }
index 1cfcb2fd2f2bcd194a32d4a6c409fba7eafe7420..8b9af0565232d353bdcbc54b0427c0bbe07629e6 100644 (file)
         CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef,
         TypeCtor,
     },
-    Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static,
-    StructField, Trait,
+    Const, ConstData, Crate, DefWithBody, GenericDef, ImplBlock, Module, Static, StructField,
+    Trait,
 };
 
 pub use hir_def::db::{
     BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
-    EnumDataQuery, ExprScopesQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
-    InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery,
-    TraitDataQuery, TypeAliasDataQuery,
+    EnumDataQuery, ExprScopesQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery,
+    InternDatabase, InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery,
+    StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
 };
 pub use hir_expand::db::{
     AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
@@ -35,9 +35,6 @@
 #[salsa::query_group(DefDatabaseStorage)]
 #[salsa::requires(AstDatabase)]
 pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
-    #[salsa::invoke(FnData::fn_data_query)]
-    fn fn_data(&self, func: Function) -> Arc<FnData>;
-
     #[salsa::invoke(ConstData::const_data_query)]
     fn const_data(&self, konst: Const) -> Arc<ConstData>;
 
index 8535629ca76d127adeff60371256c357603dbecd..d29cc92580656f18c98ae8eea80c34dfd9209968 100644 (file)
@@ -55,9 +55,9 @@ fn from(it: $sv) -> $e {
         docs::{DocDef, Docs, Documentation},
         src::{HasBodySource, HasSource},
         Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum,
-        EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock,
-        Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField,
-        Trait, TypeAlias, Union, VariantDef,
+        EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasBody, ImplBlock, Local,
+        MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait,
+        TypeAlias, Union, VariantDef,
     },
     expr::ExprScopes,
     from_source::FromSource,
index 69b13baefbace0f6b5ea5fbe92f1d11d403e6325..41a51283d67363f90de2734e6b34a7a2a3d28d5f 100644 (file)
@@ -22,6 +22,7 @@
 use rustc_hash::FxHashMap;
 
 use hir_def::{
+    function::FunctionData,
     path::known,
     resolver::{HasResolver, Resolver, TypeNs},
     type_ref::{Mutability, TypeRef},
@@ -43,8 +44,8 @@
     db::HirDatabase,
     expr::{BindingAnnotation, Body, ExprId, PatId},
     ty::infer::diagnostics::InferenceDiagnostic,
-    Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path,
-    StructField, Trait, VariantDef,
+    Adt, AssocItem, ConstData, DefWithBody, FloatTy, Function, HasBody, IntTy, Path, StructField,
+    Trait, VariantDef,
 };
 
 macro_rules! ty_app {
@@ -70,7 +71,7 @@ pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResu
 
     match def {
         DefWithBody::Const(ref c) => ctx.collect_const(&c.data(db)),
-        DefWithBody::Function(ref f) => ctx.collect_fn(&f.data(db)),
+        DefWithBody::Function(ref f) => ctx.collect_fn(&db.function_data(f.id)),
         DefWithBody::Static(ref s) => ctx.collect_const(&s.data(db)),
     }
 
@@ -562,14 +563,14 @@ fn collect_const(&mut self, data: &ConstData) {
         self.return_ty = self.make_ty(data.type_ref());
     }
 
-    fn collect_fn(&mut self, data: &FnData) {
+    fn collect_fn(&mut self, data: &FunctionData) {
         let body = Arc::clone(&self.body); // avoid borrow checker problem
-        for (type_ref, pat) in data.params().iter().zip(body.params()) {
+        for (type_ref, pat) in data.params.iter().zip(body.params()) {
             let ty = self.make_ty(type_ref);
 
             self.infer_pat(*pat, &ty, BindingMode::default());
         }
-        self.return_ty = self.make_ty(data.ret_type());
+        self.return_ty = self.make_ty(&data.ret_type);
     }
 
     fn infer_body(&mut self) {
index 75c55256929a84f6831427628067030ca841e0c5..42daa9cb93989955df7e684511a4bbd308f6f4b9 100644 (file)
@@ -622,10 +622,10 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
 }
 
 fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig {
-    let data = def.data(db);
+    let data = db.function_data(def.id);
     let resolver = def.id.resolver(db);
-    let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
-    let ret = Ty::from_hir(db, &resolver, data.ret_type());
+    let params = data.params.iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
+    let ret = Ty::from_hir(db, &resolver, &data.ret_type);
     FnSig::from_params_and_return(params, ret)
 }
 
index 64adb814d3f90b7e80c197c6a293df7dfd1f0664..f84aae26eee755f488ea0eae7f52c102a09cee22 100644 (file)
@@ -291,9 +291,9 @@ fn is_valid_candidate(
 ) -> bool {
     match item {
         AssocItem::Function(m) => {
-            let data = m.data(db);
-            name.map_or(true, |name| data.name() == name)
-                && (data.has_self_param() || mode == LookupMode::Path)
+            let data = db.function_data(m.id);
+            name.map_or(true, |name| data.name == *name)
+                && (data.has_self_param || mode == LookupMode::Path)
         }
         AssocItem::Const(c) => {
             name.map_or(true, |name| Some(name) == c.name(db).as_ref())
index 5bbdaa4b20ad28049afafb85847c049138e723be..02e649cc7421a97bd3d3c63feea8b5862e314d78 100644 (file)
@@ -8,6 +8,7 @@
 use crate::{
     adt::{EnumData, StructData},
     body::{scope::ExprScopes, Body, BodySourceMap},
+    function::FunctionData,
     generics::GenericParams,
     impls::ImplData,
     nameres::{
@@ -16,7 +17,8 @@
     },
     traits::TraitData,
     type_alias::TypeAliasData,
-    DefWithBodyId, EnumId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId, TypeAliasId,
+    DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StructOrUnionId, TraitId,
+    TypeAliasId,
 };
 
 #[salsa::query_group(InternDatabaseStorage)]
@@ -68,6 +70,9 @@ fn raw_items_with_source_map(
     #[salsa::invoke(TypeAliasData::type_alias_data_query)]
     fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
 
+    #[salsa::invoke(FunctionData::fn_data_query)]
+    fn function_data(&self, func: FunctionId) -> Arc<FunctionData>;
+
     #[salsa::invoke(Body::body_with_source_map_query)]
     fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
 
diff --git a/crates/ra_hir_def/src/function.rs b/crates/ra_hir_def/src/function.rs
new file mode 100644 (file)
index 0000000..3326527
--- /dev/null
@@ -0,0 +1,61 @@
+use std::sync::Arc;
+
+use hir_expand::name::{self, AsName, Name};
+use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
+
+use crate::{
+    db::DefDatabase2,
+    type_ref::{Mutability, TypeRef},
+    FunctionId, HasSource, Lookup,
+};
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FunctionData {
+    pub name: Name,
+    pub params: Vec<TypeRef>,
+    pub ret_type: TypeRef,
+    /// True if the first param is `self`. This is relevant to decide whether this
+    /// can be called as a method.
+    pub has_self_param: bool,
+}
+
+impl FunctionData {
+    pub(crate) fn fn_data_query(db: &impl DefDatabase2, func: FunctionId) -> Arc<FunctionData> {
+        let src = func.lookup(db).source(db);
+        let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
+        let mut params = Vec::new();
+        let mut has_self_param = false;
+        if let Some(param_list) = src.value.param_list() {
+            if let Some(self_param) = param_list.self_param() {
+                let self_type = if let Some(type_ref) = self_param.ascribed_type() {
+                    TypeRef::from_ast(type_ref)
+                } else {
+                    let self_type = TypeRef::Path(name::SELF_TYPE.into());
+                    match self_param.kind() {
+                        ast::SelfParamKind::Owned => self_type,
+                        ast::SelfParamKind::Ref => {
+                            TypeRef::Reference(Box::new(self_type), Mutability::Shared)
+                        }
+                        ast::SelfParamKind::MutRef => {
+                            TypeRef::Reference(Box::new(self_type), Mutability::Mut)
+                        }
+                    }
+                };
+                params.push(self_type);
+                has_self_param = true;
+            }
+            for param in param_list.params() {
+                let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
+                params.push(type_ref);
+            }
+        }
+        let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) {
+            TypeRef::from_ast(type_ref)
+        } else {
+            TypeRef::unit()
+        };
+
+        let sig = FunctionData { name, params, ret_type, has_self_param };
+        Arc::new(sig)
+    }
+}
index 26814446296f78298adc927fed8bfba3bf3ed729..14ccad043dfd2fb372fe751ba0000956fab30dd1 100644 (file)
@@ -21,6 +21,7 @@
 pub mod traits;
 pub mod resolver;
 pub mod type_alias;
+pub mod function;
 
 #[cfg(test)]
 mod test_db;
index 41ee81511219bced3e8a43a6cdabfe83424538db..7c367230e7192c753e574b8dfa6995ad96c75fc2 100644 (file)
@@ -30,7 +30,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
             let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?;
             match callable_def {
                 hir::CallableDef::Function(it) => {
-                    (CallInfo::with_fn(db, it), it.data(db).has_self_param())
+                    (CallInfo::with_fn(db, it), it.has_self_param(db))
                 }
                 hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false),
                 hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false),
@@ -38,7 +38,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
         }
         FnCallNode::MethodCallExpr(expr) => {
             let function = analyzer.resolve_method_call(&expr)?;
-            (CallInfo::with_fn(db, function), function.data(db).has_self_param())
+            (CallInfo::with_fn(db, function), function.has_self_param(db))
         }
         FnCallNode::MacroCallExpr(expr) => {
             let macro_def = analyzer.resolve_macro_call(db, &expr)?;
index 3c607d5b53c40c7a03e90014dd1bff3f5cb46cb7..8a05b287f7107e15a18710f6b728629c45220ece 100644 (file)
@@ -313,7 +313,7 @@ macro_rules! sweep_each_query {
             hir::db::RawItemsQuery
             hir::db::CrateDefMapQuery
             hir::db::GenericParamsQuery
-            hir::db::FnDataQuery
+            hir::db::FunctionDataQuery
             hir::db::TypeAliasDataQuery
             hir::db::ConstDataQuery
             hir::db::StaticDataQuery
index 4e2c497e1db85e2ef84b92a40d5916cbf0f28cf8..5a3f9b5f64a329a2cfb654fe69dd7391a75f1945 100644 (file)
@@ -59,8 +59,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty)
 fn complete_methods(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) {
     let mut seen_methods = FxHashSet::default();
     ctx.analyzer.iterate_method_candidates(ctx.db, receiver, None, |_ty, func| {
-        let data = func.data(ctx.db);
-        if data.has_self_param() && seen_methods.insert(data.name().clone()) {
+        if func.has_self_param(ctx.db) && seen_methods.insert(func.name(ctx.db)) {
             acc.add_function(ctx, func);
         }
         None::<()>
index 5d974cf6d56d60979c2d8137faa362407a7704a9..802c7701a34870d42efe67de72769a79e0de09cc 100644 (file)
@@ -53,8 +53,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
             ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| {
                 match item {
                     hir::AssocItem::Function(func) => {
-                        let data = func.data(ctx.db);
-                        if !data.has_self_param() {
+                        if !func.has_self_param(ctx.db) {
                             acc.add_function(ctx, func);
                         }
                     }
@@ -80,8 +79,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
             for item in t.items(ctx.db) {
                 match item {
                     hir::AssocItem::Function(func) => {
-                        let data = func.data(ctx.db);
-                        if !data.has_self_param() {
+                        if !func.has_self_param(ctx.db) {
                             acc.add_function(ctx, func);
                         }
                     }
index bd464d193eeb0e62d4e23e578f542d63b9503673..50fdb0043e634b71568c715e50a3e5a0f642252f 100644 (file)
@@ -199,14 +199,17 @@ fn add_function_with_name(
         name: Option<String>,
         func: hir::Function,
     ) {
-        let data = func.data(ctx.db);
-        let name = name.unwrap_or_else(|| data.name().to_string());
+        let func_name = func.name(ctx.db);
+        let has_self_param = func.has_self_param(ctx.db);
+        let params = func.params(ctx.db);
+
+        let name = name.unwrap_or_else(|| func_name.to_string());
         let ast_node = func.source(ctx.db).value;
         let detail = function_label(&ast_node);
 
         let mut builder =
             CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone())
-                .kind(if data.has_self_param() {
+                .kind(if has_self_param {
                     CompletionItemKind::Method
                 } else {
                     CompletionItemKind::Function
@@ -222,10 +225,10 @@ fn add_function_with_name(
         {
             tested_by!(inserts_parens_for_function_calls);
             let (snippet, label) =
-                if data.params().is_empty() || data.has_self_param() && data.params().len() == 1 {
-                    (format!("{}()$0", data.name()), format!("{}()", name))
+                if params.is_empty() || has_self_param && params.len() == 1 {
+                    (format!("{}()$0", func_name), format!("{}()", name))
                 } else {
-                    (format!("{}($0)", data.name()), format!("{}(…)", name))
+                    (format!("{}($0)", func_name), format!("{}(…)", name))
                 };
             builder = builder.lookup_by(name).label(label).insert_snippet(snippet);
         }