Pass attributes as token tree to DefCollector

This commit is contained in:
uHOOCCOOHu 2019-09-30 02:50:56 +08:00
parent ba3ec8b150
commit ffe179a736
No known key found for this signature in database
GPG key ID: CED392DE0C483D00
4 changed files with 54 additions and 21 deletions

View file

@ -523,7 +523,7 @@ where
// `#[macro_use] extern crate` is hoisted to imports macros before collecting
// any other items.
for item in items {
if let raw::RawItem::Import(import_id) = *item {
if let raw::RawItemKind::Import(import_id) = item.kind {
let import = self.raw_items[import_id].clone();
if import.is_extern_crate && import.is_macro_use {
self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
@ -532,15 +532,14 @@ where
}
for item in items {
match *item {
raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]),
raw::RawItem::Import(import_id) => self.def_collector.unresolved_imports.push((
self.module_id,
import_id,
self.raw_items[import_id].clone(),
)),
raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]),
raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]),
match item.kind {
raw::RawItemKind::Module(m) => self.collect_module(&self.raw_items[m]),
raw::RawItemKind::Import(import_id) => self
.def_collector
.unresolved_imports
.push((self.module_id, import_id, self.raw_items[import_id].clone())),
raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]),
raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]),
}
}
}

View file

@ -2,6 +2,7 @@
use std::{ops::Index, sync::Arc};
use mbe::ast_to_token_tree;
use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
use ra_syntax::{
ast::{self, AttrsOwner, NameOwner},
@ -28,6 +29,8 @@ pub struct RawItems {
items: Vec<RawItem>,
}
type Attrs = Arc<[tt::Subtree]>;
#[derive(Debug, Default, PartialEq, Eq)]
pub struct ImportSourceMap {
map: ArenaMap<ImportId, ImportSourcePtr>,
@ -119,8 +122,14 @@ impl Index<Macro> for RawItems {
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub(super) struct RawItem {
pub(super) attrs: Attrs,
pub(super) kind: RawItemKind,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub(super) enum RawItem {
pub(super) enum RawItemKind {
Module(Module),
Import(ImportId),
Def(Def),
@ -215,6 +224,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
}
fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
let attrs = self.parse_attrs(&item);
let (kind, name) = match item {
ast::ModuleItem::Module(module) => {
self.add_module(current_module, module);
@ -263,7 +273,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
if let Some(name) = name {
let name = name.as_name();
let def = self.raw_items.defs.alloc(DefData { name, kind });
self.push_item(current_module, RawItem::Def(def))
self.push_item(current_module, attrs, RawItemKind::Def(def));
}
}
@ -272,6 +282,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
Some(it) => it.as_name(),
None => return,
};
let attrs = self.parse_attrs(&module);
let ast_id = self.source_ast_id_map.ast_id(&module);
let is_macro_use = module.has_atom_attr("macro_use");
@ -283,7 +294,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
attr_path,
is_macro_use,
});
self.push_item(current_module, RawItem::Module(item));
self.push_item(current_module, attrs, RawItemKind::Module(item));
return;
}
@ -297,7 +308,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
is_macro_use,
});
self.process_module(Some(item), item_list);
self.push_item(current_module, RawItem::Module(item));
self.push_item(current_module, attrs, RawItemKind::Module(item));
return;
}
tested_by!(name_res_works_for_broken_modules);
@ -305,6 +316,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) {
let is_prelude = use_item.has_atom_attr("prelude_import");
let attrs = self.parse_attrs(&use_item);
Path::expand_use_item(
Source { ast: use_item, file_id: self.file_id },
@ -318,7 +330,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
is_extern_crate: false,
is_macro_use: false,
};
self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree)));
self.push_import(
current_module,
attrs.clone(),
import_data,
Either::A(AstPtr::new(use_tree)),
);
},
)
}
@ -331,6 +348,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
if let Some(name_ref) = extern_crate.name_ref() {
let path = Path::from_name_ref(&name_ref);
let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
let attrs = self.parse_attrs(&extern_crate);
let is_macro_use = extern_crate.has_atom_attr("macro_use");
let import_data = ImportData {
path,
@ -340,7 +358,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
is_extern_crate: true,
is_macro_use,
};
self.push_import(current_module, import_data, Either::B(AstPtr::new(&extern_crate)));
self.push_import(
current_module,
attrs,
import_data,
Either::B(AstPtr::new(&extern_crate)),
);
}
}
@ -358,21 +381,22 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export");
let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
self.push_item(current_module, RawItem::Macro(m));
self.push_item(current_module, attrs, RawItemKind::Macro(m));
}
fn push_import(
&mut self,
current_module: Option<Module>,
attrs: Attrs,
data: ImportData,
source: ImportSourcePtr,
) {
let import = self.raw_items.imports.alloc(data);
self.source_map.insert(import, source);
self.push_item(current_module, RawItem::Import(import))
self.push_item(current_module, attrs, RawItemKind::Import(import))
}
fn push_item(&mut self, current_module: Option<Module>, item: RawItem) {
fn push_item(&mut self, current_module: Option<Module>, attrs: Attrs, kind: RawItemKind) {
match current_module {
Some(module) => match &mut self.raw_items.modules[module] {
ModuleData::Definition { items, .. } => items,
@ -380,7 +404,15 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
},
None => &mut self.raw_items.items,
}
.push(item)
.push(RawItem { attrs, kind })
}
fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
item.attrs()
.flat_map(|attr| attr.value())
.flat_map(|tt| ast_to_token_tree(&tt))
.map(|(tt, _)| tt)
.collect()
}
}

View file

@ -1962,6 +1962,7 @@ impl AstNode for ModuleItem {
}
}
}
impl ast::AttrsOwner for ModuleItem {}
impl ModuleItem {}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Name {

View file

@ -397,7 +397,8 @@ Grammar(
),
"ModuleItem": (
enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
"UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ]
"UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
traits: ["AttrsOwner"]
),
"ImplItem": (
enum: ["FnDef", "TypeAliasDef", "ConstDef"]