Change to use Expansion::file_id and reordering

This commit is contained in:
Edwin Cheng 2019-11-19 22:56:28 +08:00
parent 8010b42b21
commit 94c63d2802
2 changed files with 40 additions and 46 deletions

View file

@ -140,12 +140,7 @@ impl Expansion {
exp_info.map_token_down(token)
}
pub fn source(&self, db: &impl HirDatabase) -> Source<AstId<ast::MacroCall>> {
let loc = db.lookup_intern_macro(self.macro_call_id);
Source::new(self.file_id(), loc.ast_id)
}
fn file_id(&self) -> HirFileId {
pub fn file_id(&self) -> HirFileId {
self.macro_call_id.as_file(MacroFileKind::Items)
}
}

View file

@ -11,6 +11,45 @@ use ra_syntax::{
AstNode, NodeOrToken, SyntaxKind, SyntaxNode, WalkEvent,
};
pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<(String, String)> {
let parse = db.parse(position.file_id);
let file = parse.tree();
let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)?;
let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?;
let source = hir::Source::new(position.file_id.into(), mac.syntax());
let expanded = expand_macro_recur(db, source, &mac)?;
// FIXME:
// macro expansion may lose all white space information
// But we hope someday we can use ra_fmt for that
let res = insert_whitespaces(expanded);
Some((name_ref.text().to_string(), res))
}
fn expand_macro_recur(
db: &RootDatabase,
source: hir::Source<&SyntaxNode>,
macro_call: &ast::MacroCall,
) -> Option<SyntaxNode> {
let analyzer = hir::SourceAnalyzer::new(db, source, None);
let expansion = analyzer.expand(db, &macro_call)?;
let macro_file_id = expansion.file_id();
let expanded: SyntaxNode = db.parse_or_expand(macro_file_id)?;
let children = expanded.descendants().filter_map(ast::MacroCall::cast);
let mut replaces = FxHashMap::default();
for child in children.into_iter() {
let source = hir::Source::new(macro_file_id, source.ast);
let new_node = expand_macro_recur(db, source, &child)?;
replaces.insert(child.syntax().clone().into(), new_node.into());
}
Some(replace_descendants(&expanded, &replaces))
}
fn insert_whitespaces(syn: SyntaxNode) -> String {
let mut res = String::new();
@ -40,46 +79,6 @@ fn insert_whitespaces(syn: SyntaxNode) -> String {
res
}
fn expand_macro_recur(
db: &RootDatabase,
source: hir::Source<&SyntaxNode>,
macro_call: &ast::MacroCall,
) -> Option<SyntaxNode> {
let analyzer = hir::SourceAnalyzer::new(db, source, None);
let expansion = analyzer.expand(db, &macro_call)?;
let new_source = expansion.source(db);
let expanded: SyntaxNode = db.parse_or_expand(new_source.file_id)?;
let children = expanded.descendants().filter_map(ast::MacroCall::cast);
let mut replaces = FxHashMap::default();
for child in children.into_iter() {
let source = new_source.with_ast(source.ast);
let new_node = expand_macro_recur(db, source, &child)?;
replaces.insert(child.syntax().clone().into(), new_node.into());
}
Some(replace_descendants(&expanded, &replaces))
}
pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<(String, String)> {
let parse = db.parse(position.file_id);
let file = parse.tree();
let name_ref = find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)?;
let mac = name_ref.syntax().ancestors().find_map(ast::MacroCall::cast)?;
let source = hir::Source::new(position.file_id.into(), mac.syntax());
let expanded = expand_macro_recur(db, source, &mac)?;
// FIXME:
// macro expansion may lose all white space information
// But we hope someday we can use ra_fmt for that
let res = insert_whitespaces(expanded);
Some((name_ref.text().to_string(), res))
}
#[cfg(test)]
mod tests {
use crate::mock_analysis::analysis_and_position;