pub(crate) mod src;
pub(crate) mod docs;
-pub(crate) mod attrs;
use std::sync::Arc;
nameres::per_ns::PerNs,
resolver::{HasResolver, TypeNs},
type_ref::TypeRef,
- ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
- ModuleId, UnionId,
+ AdtId, ContainerId, CrateModuleId, EnumVariantId, HasModule, ImplId, LocalEnumVariantId,
+ LocalStructFieldId, Lookup, ModuleId, StructFieldId, UnionId,
};
use hir_expand::{
diagnostics::DiagnosticSink,
BuiltinType
);
-pub use hir_def::ModuleSource;
+pub use hir_def::{attr::Attrs, ModuleSource};
impl Module {
pub(crate) fn new(krate: Crate, crate_module_id: CrateModuleId) -> Module {
.unwrap_or(ScopeDef::Unknown)
}
}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum AttrDef {
+ Module(Module),
+ StructField(StructField),
+ Adt(Adt),
+ Function(Function),
+ EnumVariant(EnumVariant),
+ Static(Static),
+ Const(Const),
+ Trait(Trait),
+ TypeAlias(TypeAlias),
+ MacroDef(MacroDef),
+}
+
+impl_froms!(
+ AttrDef: Module,
+ StructField,
+ Adt(Struct, Enum, Union),
+ EnumVariant,
+ Static,
+ Const,
+ Function,
+ Trait,
+ TypeAlias,
+ MacroDef
+);
+
+pub trait HasAttrs {
+ fn attrs(self, db: &impl DefDatabase) -> Attrs;
+}
+
+impl<T: Into<AttrDef>> HasAttrs for T {
+ fn attrs(self, db: &impl DefDatabase) -> Attrs {
+ let def = self.into();
+ match def {
+ AttrDef::Module(it) => db.attrs(it.id.into()),
+ AttrDef::StructField(it) => db.attrs(StructFieldId::from(it).into()),
+ AttrDef::Adt(it) => db.attrs(AdtId::from(it).into()),
+ AttrDef::Function(it) => db.attrs(it.id.into()),
+ AttrDef::EnumVariant(it) => db.attrs(EnumVariantId::from(it).into()),
+ AttrDef::Static(it) => db.attrs(it.id.into()),
+ AttrDef::Const(it) => db.attrs(it.id.into()),
+ AttrDef::Trait(it) => db.attrs(it.id.into()),
+ AttrDef::TypeAlias(it) => db.attrs(it.id.into()),
+ AttrDef::MacroDef(it) => db.attrs(it.id.into()),
+ }
+ }
+}
+++ /dev/null
-//! FIXME: write short doc here
-
-use crate::{
- db::{AstDatabase, DefDatabase, HirDatabase},
- Adt, Const, Enum, EnumVariant, FieldSource, Function, HasSource, MacroDef, Module, Static,
- Struct, StructField, Trait, TypeAlias, Union,
-};
-use hir_def::attr::{Attr, Attrs};
-use hir_expand::hygiene::Hygiene;
-use ra_syntax::ast;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum AttrDef {
- Module(Module),
- StructField(StructField),
- Adt(Adt),
- Function(Function),
- EnumVariant(EnumVariant),
- Static(Static),
- Const(Const),
- Trait(Trait),
- TypeAlias(TypeAlias),
- MacroDef(MacroDef),
-}
-
-impl_froms!(
- AttrDef: Module,
- StructField,
- Adt(Struct, Enum, Union),
- EnumVariant,
- Static,
- Const,
- Function,
- Trait,
- TypeAlias,
- MacroDef
-);
-
-pub trait HasAttrs {
- fn attrs(&self, db: &impl HirDatabase) -> Attrs;
-}
-
-pub(crate) fn attributes_query(db: &(impl DefDatabase + AstDatabase), def: AttrDef) -> Attrs {
- match def {
- AttrDef::Module(it) => {
- let src = match it.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)
- }
- AttrDef::StructField(it) => match it.source(db).value {
- FieldSource::Named(named) => {
- let src = it.source(db);
- let hygiene = Hygiene::new(db, src.file_id);
- Attr::from_attrs_owner(&named, &hygiene)
- }
- FieldSource::Pos(..) => Attrs::default(),
- },
- AttrDef::Adt(it) => match it {
- Adt::Struct(it) => attrs_from_ast(it, db),
- Adt::Enum(it) => attrs_from_ast(it, db),
- Adt::Union(it) => attrs_from_ast(it, db),
- },
- AttrDef::EnumVariant(it) => attrs_from_ast(it, db),
- AttrDef::Static(it) => attrs_from_ast(it, db),
- AttrDef::Const(it) => attrs_from_ast(it, db),
- AttrDef::Function(it) => attrs_from_ast(it, db),
- AttrDef::Trait(it) => attrs_from_ast(it, db),
- AttrDef::TypeAlias(it) => attrs_from_ast(it, db),
- AttrDef::MacroDef(it) => attrs_from_ast(it, db),
- }
-}
-
-fn attrs_from_ast<T, D>(node: T, db: &D) -> Attrs
-where
- T: HasSource,
- T::Ast: ast::AttrsOwner,
- D: DefDatabase + AstDatabase,
-{
- let src = node.source(db);
- let hygiene = Hygiene::new(db, src.file_id);
- Attr::from_attrs_owner(&src.value, &hygiene)
-}
-
-impl<T: Into<AttrDef> + Copy> HasAttrs for T {
- fn attrs(&self, db: &impl HirDatabase) -> Attrs {
- db.attrs((*self).into())
- }
-}
//! FIXME: write short doc here
use hir_def::{HasChildSource, HasSource as _, Lookup, VariantId};
+use hir_expand::either::Either;
use ra_syntax::ast::{self, AstNode};
use crate::{
db::{AstDatabase, DefDatabase, HirDatabase},
ids::AstItemDef,
- Const, Either, Enum, EnumVariant, FieldSource, Function, HasBody, HirFileId, MacroDef, Module,
- ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
+ Const, Enum, EnumVariant, FieldSource, Function, HasBody, MacroDef, Module, ModuleSource,
+ Static, Struct, StructField, Trait, TypeAlias, Union,
};
pub use hir_expand::Source;
/// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> {
let def_map = db.crate_def_map(self.id.krate);
- let decl_id = def_map[self.id.module_id].declaration;
- let file_id = def_map[self.id.module_id].definition;
- let value = ModuleSource::new(db, file_id, decl_id);
- let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
- Source { file_id, value }
+ let src = def_map[self.id.module_id].definition_source(db);
+ src.map(|it| match it {
+ Either::A(it) => ModuleSource::SourceFile(it),
+ Either::B(it) => ModuleSource::Module(it),
+ })
}
/// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
db: &(impl DefDatabase + AstDatabase),
) -> Option<Source<ast::Module>> {
let def_map = db.crate_def_map(self.id.krate);
- let decl = def_map[self.id.module_id].declaration?;
- let value = decl.to_node(db);
- Some(Source { file_id: decl.file_id(), value })
+ def_map[self.id.module_id].declaration_source(db)
}
}
use std::sync::Arc;
-use hir_def::attr::Attrs;
use ra_db::salsa;
use ra_syntax::SmolStr;
#[salsa::invoke(crate::code_model::docs::documentation_query)]
fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>;
-
- #[salsa::invoke(crate::code_model::attrs::attributes_query)]
- fn attrs(&self, def: crate::AttrDef) -> Attrs;
}
#[salsa::query_group(HirDatabaseStorage)]
use hir_def::{
AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
- ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, VariantId,
+ ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId,
};
use crate::{
ty::{CallableDef, TypableDef},
Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef,
- Static, TypeAlias, VariantDef,
+ Static, StructField, TypeAlias, VariantDef,
};
impl From<ra_db::CrateId> for Crate {
}
}
}
+
+impl From<StructField> for StructFieldId {
+ fn from(def: StructField) -> Self {
+ StructFieldId { parent: def.parent.into(), local_id: def.id }
+ }
+}
pub use crate::{
code_model::{
- attrs::{AttrDef, HasAttrs},
docs::{DocDef, Docs, Documentation},
src::{HasBodySource, HasSource},
- Adt, AssocItem, Const, Container, Crate, CrateDependency, DefWithBody, Enum, EnumVariant,
- FieldSource, Function, GenericDef, GenericParam, HasBody, ImplBlock, Local, MacroDef,
- Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, TypeAlias,
- Union, VariantDef,
+ Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Enum,
+ EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock,
+ Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField,
+ Trait, TypeAlias, Union, VariantDef,
},
expr::ExprScopes,
from_source::FromSource,
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::{
};
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 {
}
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))
}
cfg_options.is_cfg_enabled(self.as_cfg()?)
}
}
+
+fn attrs_from_ast<D, N>(src: AstId<N>, 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<T, D>(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)
+}
use crate::{
adt::{EnumData, StructData},
+ attr::Attrs,
body::{scope::ExprScopes, Body, BodySourceMap},
data::{ConstData, FunctionData, ImplData, TraitData, TypeAliasData},
generics::GenericParams,
raw::{ImportSourceMap, RawItems},
CrateDefMap,
},
- ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId,
+ AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId, GenericDefId, ImplId, ItemLoc, StaticId,
StructOrUnionId, TraitId, TypeAliasId,
};
#[salsa::invoke(GenericParams::generic_params_query)]
fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
+
+ #[salsa::invoke(Attrs::attrs_query)]
+ fn attrs(&self, def: AttrDefId) -> Attrs;
}
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};
#[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)]
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;
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};
pub parent: Option<CrateModuleId>,
pub children: FxHashMap<Name, CrateModuleId>,
pub scope: ModuleScope,
+
+ // FIXME: these can't be both null, we need a three-state enum here.
/// None for root
pub declaration: Option<AstId<ast::Module>>,
/// None for inline modules.
///
/// Note that non-inline modules, by definition, live inside non-macro file.
pub definition: Option<FileId>,
+
pub impls: Vec<ImplId>,
}
}
}
+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<Either<ast::SourceFile, ast::Module>> {
+ 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<Source<ast::Module>> {
+ 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;