From c4aa8b63bcea5faa23da56b679cafbdbad6892f1 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Mon, 11 Nov 2019 14:15:09 +0800 Subject: Add line macro and tests --- crates/ra_hir_expand/src/builtin_macro.rs | 70 ++++++++++++++++++++++++++++--- crates/ra_hir_expand/src/db.rs | 2 +- 2 files changed, 65 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir_expand/src') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index dca2f17ef..acb62da27 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -1,14 +1,28 @@ //! Builtin macro -use crate::{ast, name, AstId, BuiltinMacro, CrateId, MacroDefId}; +use crate::db::AstDatabase; +use crate::{ + ast::{self, AstNode}, + name, AstId, BuiltinMacro, CrateId, HirFileId, MacroCallId, MacroDefId, MacroFileKind, + TextUnit, +}; + +use crate::quote; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BuiltinExpander { - Line + Line, } impl BuiltinExpander { - pub fn expand(&self, _tt: &tt::Subtree) -> Result { - Err(mbe::ExpandError::UnexpectedToken) + pub fn expand( + &self, + db: &dyn AstDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> Result { + match self { + BuiltinExpander::Line => line_expand(db, id, tt), + } } } @@ -18,9 +32,53 @@ pub fn find_builtin_macro( ast_id: AstId, ) -> Option { // FIXME: Better registering method - if ident == &name::LINE { - Some(MacroDefId::BuiltinMacro(BuiltinMacro { expander: BuiltinExpander::Line, krate, ast_id })) + if ident == &name::LINE_MACRO { + Some(MacroDefId::BuiltinMacro(BuiltinMacro { + expander: BuiltinExpander::Line, + krate, + ast_id, + })) } else { None } } + +fn to_line_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 line_num = 1; + + // Count line end + for (i, c) in text.chars().enumerate() { + if i == pos.to_usize() { + break; + } + if c == '\n' { + line_num += 1; + } + } + + line_num +} + +fn line_expand( + db: &dyn AstDatabase, + id: MacroCallId, + _tt: &tt::Subtree, +) -> Result { + 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 arg_start = arg.syntax().text_range().start(); + + let file = id.as_file(MacroFileKind::Expr); + let line_num = to_line_number(db, file, arg_start); + + let expanded = quote! { + #line_num + }; + + Ok(expanded) +} diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 343c9e6bf..009ff5312 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -28,7 +28,7 @@ impl TokenExpander { ) -> Result { match self { TokenExpander::MacroRules(it) => it.expand(tt), - TokenExpander::Builtin(it) => it.expand(tt), + TokenExpander::Builtin(it) => it.expand(db, id, tt), } } -- cgit v1.2.3