From 552ba868afc8f72202ac834d07bbeb330aca007d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Nov 2019 11:14:10 +0300 Subject: Move attrs query to hir_def --- crates/ra_hir_def/src/attr.rs | 66 ++++++++++++++++++++++++++++++++++++++-- crates/ra_hir_def/src/db.rs | 6 +++- crates/ra_hir_def/src/lib.rs | 33 ++++++++++++++++++-- crates/ra_hir_def/src/nameres.rs | 31 ++++++++++++++++++- 4 files changed, 129 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 7a9d0fdf4..ce397f6b0 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -2,7 +2,7 @@ use std::{ops, sync::Arc}; -use hir_expand::hygiene::Hygiene; +use hir_expand::{either::Either, hygiene::Hygiene, AstId}; use mbe::ast_to_token_tree; use ra_cfg::CfgOptions; use ra_syntax::{ @@ -11,7 +11,9 @@ use ra_syntax::{ }; use tt::Subtree; -use crate::path::Path; +use crate::{ + db::DefDatabase2, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup, +}; #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Attrs { @@ -30,6 +32,46 @@ impl ops::Deref for Attrs { } impl Attrs { + pub(crate) fn attrs_query(db: &impl DefDatabase2, def: AttrDefId) -> Attrs { + match def { + AttrDefId::ModuleId(module) => { + let def_map = db.crate_def_map(module.krate); + let src = match def_map[module.module_id].declaration_source(db) { + Some(it) => it, + None => return Attrs::default(), + }; + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(&src.value, &hygiene) + } + AttrDefId::StructFieldId(it) => { + let src = it.parent.child_source(db); + match &src.value[it.local_id] { + Either::A(_tuple) => Attrs::default(), + Either::B(record) => { + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(record, &hygiene) + } + } + } + AttrDefId::AdtId(it) => match it { + AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), + }, + AttrDefId::EnumVariantId(it) => { + let src = it.parent.child_source(db); + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) + } + AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), + } + } + pub fn has_atom(&self, atom: &str) -> bool { self.iter().any(|it| it.is_simple_atom(atom)) } @@ -106,3 +148,23 @@ impl Attr { cfg_options.is_cfg_enabled(self.as_cfg()?) } } + +fn attrs_from_ast(src: AstId, db: &D) -> Attrs +where + N: ast::AttrsOwner, + D: DefDatabase2, +{ + let hygiene = Hygiene::new(db, src.file_id()); + Attr::from_attrs_owner(&src.to_node(db), &hygiene) +} + +fn attrs_from_loc(node: T, db: &D) -> Attrs +where + T: HasSource, + T::Value: ast::AttrsOwner, + D: DefDatabase2, +{ + let src = node.source(db); + let hygiene = Hygiene::new(db, src.file_id); + Attr::from_attrs_owner(&src.value, &hygiene) +} diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 2c660ab88..e91e741bb 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -7,6 +7,7 @@ use ra_syntax::ast; use crate::{ adt::{EnumData, StructData}, + attr::Attrs, body::{scope::ExprScopes, Body, BodySourceMap}, data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData}, generics::GenericParams, @@ -14,7 +15,7 @@ use crate::{ raw::{ImportSourceMap, RawItems}, CrateDefMap, }, - ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId, + AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId, StructOrUnionId, TraitId, TypeAliasId, }; @@ -87,4 +88,7 @@ pub trait DefDatabase2: InternDatabase + AstDatabase { #[salsa::invoke(GenericParams::generic_params_query)] fn generic_params(&self, def: GenericDefId) -> Arc; + + #[salsa::invoke(Attrs::attrs_query)] + fn attrs(&self, def: AttrDefId) -> Attrs; } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 2edf743ab..1bcdf9b78 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -32,7 +32,7 @@ pub mod nameres; use std::hash::{Hash, Hasher}; -use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, Source}; +use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; use ra_db::{salsa, CrateId, FileId}; use ra_syntax::{ast, AstNode, SyntaxNode}; @@ -280,8 +280,8 @@ pub enum VariantId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StructFieldId { - parent: VariantId, - local_id: LocalStructFieldId, + pub parent: VariantId, + pub local_id: LocalStructFieldId, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -477,6 +477,33 @@ impl_froms!( ConstId ); +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum AttrDefId { + ModuleId(ModuleId), + StructFieldId(StructFieldId), + AdtId(AdtId), + FunctionId(FunctionId), + EnumVariantId(EnumVariantId), + StaticId(StaticId), + ConstId(ConstId), + TraitId(TraitId), + TypeAliasId(TypeAliasId), + MacroDefId(MacroDefId), +} + +impl_froms!( + AttrDefId: ModuleId, + StructFieldId, + AdtId(StructId, EnumId, UnionId), + EnumVariantId, + StaticId, + ConstId, + FunctionId, + TraitId, + TypeAliasId, + MacroDefId +); + trait Intern { type ID; fn intern(self, db: &impl db::DefDatabase2) -> Self::ID; diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index c01e020ef..6723465a5 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -58,7 +58,10 @@ mod tests; use std::sync::Arc; -use hir_expand::{ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, MacroDefId}; +use hir_expand::{ + ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId, + Source, +}; use once_cell::sync::Lazy; use ra_arena::Arena; use ra_db::{CrateId, Edition, FileId}; @@ -116,12 +119,15 @@ pub struct ModuleData { pub parent: Option, pub children: FxHashMap, pub scope: ModuleScope, + + // FIXME: these can't be both null, we need a three-state enum here. /// None for root pub declaration: Option>, /// None for inline modules. /// /// Note that non-inline modules, by definition, live inside non-macro file. pub definition: Option, + pub impls: Vec, } @@ -285,6 +291,29 @@ impl CrateDefMap { } } +impl ModuleData { + /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. + pub fn definition_source( + &self, + db: &impl DefDatabase2, + ) -> Source> { + if let Some(file_id) = self.definition { + let sf = db.parse(file_id).tree(); + return Source::new(file_id.into(), Either::A(sf)); + } + let decl = self.declaration.unwrap(); + Source::new(decl.file_id(), Either::B(decl.to_node(db))) + } + + /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. + /// `None` for the crate root. + pub fn declaration_source(&self, db: &impl DefDatabase2) -> Option> { + let decl = self.declaration?; + let value = decl.to_node(db); + Some(Source { file_id: decl.file_id(), value }) + } +} + mod diagnostics { use hir_expand::diagnostics::DiagnosticSink; use ra_db::RelativePathBuf; -- cgit v1.2.3