comments
This commit is contained in:
parent
4fe0ec5497
commit
35b3fc02e0
@ -29,6 +29,8 @@ use crate::{
|
||||
pub struct HirFileId(HirFileIdRepr);
|
||||
|
||||
impl HirFileId {
|
||||
/// For macro-expansion files, returns the file original source file the
|
||||
/// expansionoriginated from.
|
||||
pub(crate) fn original_file_id(self, db: &impl HirDatabase) -> FileId {
|
||||
match self.0 {
|
||||
HirFileIdRepr::File(file_id) => file_id,
|
||||
@ -45,6 +47,7 @@ impl HirFileId {
|
||||
HirFileIdRepr::Macro(_r) => panic!("macro generated file: {:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn hir_source_file(db: &impl HirDatabase, file_id: HirFileId) -> SourceFileNode {
|
||||
match file_id.0 {
|
||||
HirFileIdRepr::File(file_id) => db.source_file(file_id),
|
||||
|
@ -25,6 +25,7 @@ pub mod source_binder;
|
||||
mod ids;
|
||||
mod macros;
|
||||
mod name;
|
||||
// can't use `crate` or `r#crate` here :(
|
||||
mod krate;
|
||||
mod module;
|
||||
mod function;
|
||||
|
@ -1,3 +1,12 @@
|
||||
/// Machinery for macro expansion.
|
||||
///
|
||||
/// One of the more complicated things about macros is managing the source code
|
||||
/// that is produced after expansion. See `HirFileId` and `MacroCallId` for how
|
||||
/// do we do that.
|
||||
///
|
||||
/// When file-management question is resolved, all that is left is a token tree
|
||||
/// to token tree transformation plus hygent. We don't have either of thouse
|
||||
/// yet, so all macros are string based at the moment!
|
||||
use std::sync::Arc;
|
||||
|
||||
use ra_db::LocalSyntaxPtr;
|
||||
@ -16,6 +25,8 @@ pub enum MacroDef {
|
||||
}
|
||||
|
||||
impl MacroDef {
|
||||
/// Expands macro call, returning the expansion and offset to be used to
|
||||
/// convert ranges between expansion and original source.
|
||||
pub fn ast_expand(macro_call: ast::MacroCall) -> Option<(TextUnit, MacroExpansion)> {
|
||||
let (def, input) = MacroDef::from_call(macro_call)?;
|
||||
let exp = def.expand(input)?;
|
||||
@ -109,14 +120,20 @@ pub struct MacroInput {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MacroExpansion {
|
||||
/// The result of macro expansion. Should be token tree as well.
|
||||
text: String,
|
||||
/// Correspondence between ranges in the original source code and ranges in
|
||||
/// the macro.
|
||||
ranges_map: Vec<(TextRange, TextRange)>,
|
||||
/// Implementation detail: internally, a macro is expanded to the whole file,
|
||||
/// even if it is an expression. This `ptr` selects the actual expansion from
|
||||
/// the expanded file.
|
||||
ptr: LocalSyntaxPtr,
|
||||
}
|
||||
|
||||
impl MacroExpansion {
|
||||
//FIXME: does not really make sense, macro expansion is not neccessary a
|
||||
//whole file.
|
||||
// FIXME: does not really make sense, macro expansion is not neccessary a
|
||||
// whole file. See `MacroExpansion::ptr` as well.
|
||||
pub(crate) fn file(&self) -> SourceFileNode {
|
||||
SourceFileNode::parse(&self.text)
|
||||
}
|
||||
@ -124,17 +141,7 @@ impl MacroExpansion {
|
||||
pub fn syntax(&self) -> SyntaxNode {
|
||||
self.ptr.resolve(&self.file())
|
||||
}
|
||||
pub fn map_range_back(&self, tgt_range: TextRange) -> Option<TextRange> {
|
||||
for (s_range, t_range) in self.ranges_map.iter() {
|
||||
if tgt_range.is_subrange(&t_range) {
|
||||
let tgt_at_zero_range = tgt_range - tgt_range.start();
|
||||
let tgt_range_offset = tgt_range.start() - t_range.start();
|
||||
let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start();
|
||||
return Some(src_range);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
/// Maps range in the source code to the range in the expanded code.
|
||||
pub fn map_range_forward(&self, src_range: TextRange) -> Option<TextRange> {
|
||||
for (s_range, t_range) in self.ranges_map.iter() {
|
||||
if src_range.is_subrange(&s_range) {
|
||||
@ -146,6 +153,18 @@ impl MacroExpansion {
|
||||
}
|
||||
None
|
||||
}
|
||||
/// Maps range in the expanded code to the range in the source code.
|
||||
pub fn map_range_back(&self, tgt_range: TextRange) -> Option<TextRange> {
|
||||
for (s_range, t_range) in self.ranges_map.iter() {
|
||||
if tgt_range.is_subrange(&t_range) {
|
||||
let tgt_at_zero_range = tgt_range - tgt_range.start();
|
||||
let tgt_range_offset = tgt_range.start() - t_range.start();
|
||||
let src_range = tgt_at_zero_range + tgt_range_offset + s_range.start();
|
||||
return Some(src_range);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn expand_macro_invocation(
|
||||
|
Loading…
x
Reference in New Issue
Block a user