Expand column!()

This commit is contained in:
Jeremy Kolb 2019-11-22 08:48:33 -05:00 committed by kjeremy
parent 506131e3e0
commit 1ee5592be2
3 changed files with 63 additions and 1 deletions

View file

@ -4876,3 +4876,22 @@ fn main() {
"### "###
); );
} }
#[test]
fn infer_builtin_macros_column() {
assert_snapshot!(
infer(r#"
#[rustc_builtin_macro]
macro_rules! column {() => {}}
fn main() {
let x = column!();
}
"#),
@r###"
![0; 2) '13': i32
[66; 92) '{ ...!(); }': ()
[76; 77) 'x': i32
"###
);
}

View file

@ -10,6 +10,7 @@ use crate::quote;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinExpander { pub enum BuiltinExpander {
Column,
File, File,
Line, Line,
Stringify, Stringify,
@ -23,6 +24,7 @@ impl BuiltinExpander {
tt: &tt::Subtree, tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> { ) -> Result<tt::Subtree, mbe::ExpandError> {
match self { match self {
BuiltinExpander::Column => column_expand(db, id, tt),
BuiltinExpander::File => file_expand(db, id, tt), BuiltinExpander::File => file_expand(db, id, tt),
BuiltinExpander::Line => line_expand(db, id, tt), BuiltinExpander::Line => line_expand(db, id, tt),
BuiltinExpander::Stringify => stringify_expand(db, id, tt), BuiltinExpander::Stringify => stringify_expand(db, id, tt),
@ -36,7 +38,9 @@ pub fn find_builtin_macro(
ast_id: AstId<ast::MacroCall>, ast_id: AstId<ast::MacroCall>,
) -> Option<MacroDefId> { ) -> Option<MacroDefId> {
// FIXME: Better registering method // FIXME: Better registering method
if ident == &name::FILE_MACRO { if ident == &name::COLUMN_MACRO {
Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Column) })
} else if ident == &name::FILE_MACRO {
Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::File) }) Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::File) })
} else if ident == &name::LINE_MACRO { } else if ident == &name::LINE_MACRO {
Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) }) Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) })
@ -110,6 +114,43 @@ fn stringify_expand(
Ok(expanded) Ok(expanded)
} }
fn to_col_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize {
// FIXME: Use expansion info
let file_id = file.original_file(db);
let text = db.file_text(file_id);
let mut col_num = 1;
for c in text[..pos.to_usize()].chars().rev() {
if c == '\n' {
break;
}
col_num = col_num + 1;
}
col_num
}
fn column_expand(
db: &dyn AstDatabase,
id: MacroCallId,
_tt: &tt::Subtree,
) -> Result<tt::Subtree, mbe::ExpandError> {
let loc = db.lookup_intern_macro(id);
let macro_call = loc.ast_id.to_node(db);
let _arg = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
let col_start = macro_call.syntax().text_range().start();
let file = id.as_file(MacroFileKind::Expr);
let col_num = to_col_number(db, file, col_start);
let expanded = quote! {
#col_num
};
Ok(expanded)
}
fn file_expand( fn file_expand(
db: &dyn AstDatabase, db: &dyn AstDatabase,
id: MacroCallId, id: MacroCallId,
@ -117,6 +158,7 @@ fn file_expand(
) -> Result<tt::Subtree, mbe::ExpandError> { ) -> Result<tt::Subtree, mbe::ExpandError> {
let loc = db.lookup_intern_macro(id); let loc = db.lookup_intern_macro(id);
let macro_call = loc.ast_id.to_node(db); let macro_call = loc.ast_id.to_node(db);
let _ = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?; let _ = macro_call.token_tree().ok_or_else(|| mbe::ExpandError::UnexpectedToken)?;
// FIXME: RA purposefully lacks knowledge of absolute file names // FIXME: RA purposefully lacks knowledge of absolute file names

View file

@ -143,5 +143,6 @@ pub const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box");
// Builtin Macros // Builtin Macros
pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file"); pub const FILE_MACRO: Name = Name::new_inline_ascii(4, b"file");
pub const COLUMN_MACRO: Name = Name::new_inline_ascii(6, b"column");
pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line"); pub const LINE_MACRO: Name = Name::new_inline_ascii(4, b"line");
pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify"); pub const STRINGIFY_MACRO: Name = Name::new_inline_ascii(9, b"stringify");