From f4e78a5f4e7601df09b579fae56a0e31b1bd3604 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 23 Nov 2019 01:11:33 +0800 Subject: Add TestDB --- crates/ra_hir_expand/src/lib.rs | 3 +++ crates/ra_hir_expand/src/test_db.rs | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 crates/ra_hir_expand/src/test_db.rs (limited to 'crates') diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 126d12fbb..f514a15e4 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -26,6 +26,9 @@ use ra_syntax::{ use crate::ast_id_map::FileAstId; use crate::builtin_macro::BuiltinExpander; +#[cfg(test)] +mod test_db; + /// Input to the analyzer is a set of files, where each file is identified by /// `FileId` and contains source code. However, another source of source code in /// Rust are macros: each macro can be thought of as producing a "temporary diff --git a/crates/ra_hir_expand/src/test_db.rs b/crates/ra_hir_expand/src/test_db.rs new file mode 100644 index 000000000..d23e75d9e --- /dev/null +++ b/crates/ra_hir_expand/src/test_db.rs @@ -0,0 +1,50 @@ +//! Database used for testing `hir_expand`. + +use std::{ + panic, + sync::{Arc, Mutex}, +}; + +use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath}; + +#[salsa::database( + ra_db::SourceDatabaseExtStorage, + ra_db::SourceDatabaseStorage, + crate::db::AstDatabaseStorage +)] +#[derive(Debug, Default)] +pub struct TestDB { + runtime: salsa::Runtime, + events: Mutex>>>, +} + +impl salsa::Database for TestDB { + fn salsa_runtime(&self) -> &salsa::Runtime { + &self.runtime + } + + fn salsa_event(&self, event: impl Fn() -> salsa::Event) { + let mut events = self.events.lock().unwrap(); + if let Some(events) = &mut *events { + events.push(event()); + } + } +} + +impl panic::RefUnwindSafe for TestDB {} + +impl FileLoader for TestDB { + fn file_text(&self, file_id: FileId) -> Arc { + FileLoaderDelegate(self).file_text(file_id) + } + fn resolve_relative_path( + &self, + anchor: FileId, + relative_path: &RelativePath, + ) -> Option { + FileLoaderDelegate(self).resolve_relative_path(anchor, relative_path) + } + fn relevant_crates(&self, file_id: FileId) -> Arc> { + FileLoaderDelegate(self).relevant_crates(file_id) + } +} -- cgit v1.2.3 From 720ab0bef8675bd4a61d0bd416bb865c864df670 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 23 Nov 2019 01:47:35 +0800 Subject: Refactor builtin macro --- crates/ra_hir_expand/src/builtin_macro.rs | 142 ++++++++++++++++++++++++++---- 1 file changed, 124 insertions(+), 18 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index 4da56529d..d551f9198 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -16,6 +16,31 @@ pub enum BuiltinExpander { Stringify, } +struct BuiltInMacroInfo { + name: name::Name, + kind: BuiltinExpander, + expand: fn( + db: &dyn AstDatabase, + id: MacroCallId, + _tt: &tt::Subtree, + ) -> Result, +} + +macro_rules! register_builtin { + ( $(($name:ident, $kind: ident) => $expand:ident),* ) => { + const BUILTIN_MACROS: &[BuiltInMacroInfo] = &[ + $(BuiltInMacroInfo { name: name::$name, kind: BuiltinExpander::$kind, expand: $expand }),* + ]; + }; +} + +register_builtin! { + (COLUMN_MACRO, Column) => column_expand, + (FILE_MACRO, File) => file_expand, + (LINE_MACRO, Line) => line_expand, + (STRINGIFY_MACRO, Stringify) => stringify_expand +} + impl BuiltinExpander { pub fn expand( &self, @@ -23,12 +48,13 @@ impl BuiltinExpander { id: MacroCallId, tt: &tt::Subtree, ) -> Result { - match self { - BuiltinExpander::Column => column_expand(db, id, tt), - BuiltinExpander::File => file_expand(db, id, tt), - BuiltinExpander::Line => line_expand(db, id, tt), - BuiltinExpander::Stringify => stringify_expand(db, id, tt), - } + let expander = BUILTIN_MACROS + .iter() + .find(|it| *self == it.kind) + .map(|it| it.expand) + .ok_or_else(|| mbe::ExpandError::ConversionError)?; + + expander(db, id, tt) } } @@ -37,18 +63,9 @@ pub fn find_builtin_macro( krate: CrateId, ast_id: AstId, ) -> Option { - // FIXME: Better registering method - 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) }) - } else if ident == &name::LINE_MACRO { - Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Line) }) - } else if ident == &name::STRINGIFY_MACRO { - Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(BuiltinExpander::Stringify) }) - } else { - None - } + let kind = BUILTIN_MACROS.iter().find(|it| *ident == it.name).map(|it| it.kind)?; + + Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(kind) }) } fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { @@ -171,3 +188,92 @@ fn file_expand( Ok(expanded) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{test_db::TestDB, MacroCallLoc}; + use ra_db::{fixture::WithFixture, SourceDatabase}; + + fn expand_builtin_macro(s: &str, expander: BuiltinExpander) -> String { + let (db, file_id) = TestDB::with_single_file(&s); + let parsed = db.parse(file_id); + let macro_calls: Vec<_> = + parsed.syntax_node().descendants().filter_map(|it| ast::MacroCall::cast(it)).collect(); + + let ast_id_map = db.ast_id_map(file_id.into()); + + // the first one should be a macro_rules + let def = MacroDefId { + krate: CrateId(0), + ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0])), + kind: MacroDefKind::BuiltIn(expander), + }; + + let loc = MacroCallLoc { + def, + ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[1])), + }; + + let id = db.intern_macro(loc); + let parsed = db.parse_or_expand(id.as_file(MacroFileKind::Expr)).unwrap(); + + parsed.text().to_string() + } + + #[test] + fn test_column_expand() { + let expanded = expand_builtin_macro( + r#" + #[rustc_builtin_macro] + macro_rules! column {() => {}} + column!() +"#, + BuiltinExpander::Column, + ); + + assert_eq!(expanded, "9"); + } + + #[test] + fn test_line_expand() { + let expanded = expand_builtin_macro( + r#" + #[rustc_builtin_macro] + macro_rules! line {() => {}} + line!() +"#, + BuiltinExpander::Line, + ); + + assert_eq!(expanded, "4"); + } + + #[test] + fn test_stringify_expand() { + let expanded = expand_builtin_macro( + r#" + #[rustc_builtin_macro] + macro_rules! stringify {() => {}} + stringify!(a b c) +"#, + BuiltinExpander::Stringify, + ); + + assert_eq!(expanded, "\"a b c\""); + } + + #[test] + fn test_file_expand() { + let expanded = expand_builtin_macro( + r#" + #[rustc_builtin_macro] + macro_rules! file {() => {}} + file!() +"#, + BuiltinExpander::File, + ); + + assert_eq!(expanded, "\"\""); + } +} -- cgit v1.2.3 From 6940ae9eab9ec8ea5fe81c8b30ccada4a62aebde Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 23 Nov 2019 21:54:39 +0800 Subject: Rename BuiltinExpander to BuiltinFnLikeExpander --- crates/ra_hir_expand/src/builtin_macro.rs | 18 +++++++++--------- crates/ra_hir_expand/src/db.rs | 6 +++--- crates/ra_hir_expand/src/lib.rs | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index d551f9198..a0069682d 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -9,7 +9,7 @@ use crate::{ use crate::quote; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum BuiltinExpander { +pub enum BuiltinFnLikeExpander { Column, File, Line, @@ -18,7 +18,7 @@ pub enum BuiltinExpander { struct BuiltInMacroInfo { name: name::Name, - kind: BuiltinExpander, + kind: BuiltinFnLikeExpander, expand: fn( db: &dyn AstDatabase, id: MacroCallId, @@ -29,7 +29,7 @@ struct BuiltInMacroInfo { macro_rules! register_builtin { ( $(($name:ident, $kind: ident) => $expand:ident),* ) => { const BUILTIN_MACROS: &[BuiltInMacroInfo] = &[ - $(BuiltInMacroInfo { name: name::$name, kind: BuiltinExpander::$kind, expand: $expand }),* + $(BuiltInMacroInfo { name: name::$name, kind: BuiltinFnLikeExpander::$kind, expand: $expand }),* ]; }; } @@ -41,7 +41,7 @@ register_builtin! { (STRINGIFY_MACRO, Stringify) => stringify_expand } -impl BuiltinExpander { +impl BuiltinFnLikeExpander { pub fn expand( &self, db: &dyn AstDatabase, @@ -195,7 +195,7 @@ mod tests { use crate::{test_db::TestDB, MacroCallLoc}; use ra_db::{fixture::WithFixture, SourceDatabase}; - fn expand_builtin_macro(s: &str, expander: BuiltinExpander) -> String { + fn expand_builtin_macro(s: &str, expander: BuiltinFnLikeExpander) -> String { let (db, file_id) = TestDB::with_single_file(&s); let parsed = db.parse(file_id); let macro_calls: Vec<_> = @@ -229,7 +229,7 @@ mod tests { macro_rules! column {() => {}} column!() "#, - BuiltinExpander::Column, + BuiltinFnLikeExpander::Column, ); assert_eq!(expanded, "9"); @@ -243,7 +243,7 @@ mod tests { macro_rules! line {() => {}} line!() "#, - BuiltinExpander::Line, + BuiltinFnLikeExpander::Line, ); assert_eq!(expanded, "4"); @@ -257,7 +257,7 @@ mod tests { macro_rules! stringify {() => {}} stringify!(a b c) "#, - BuiltinExpander::Stringify, + BuiltinFnLikeExpander::Stringify, ); assert_eq!(expanded, "\"a b c\""); @@ -271,7 +271,7 @@ mod tests { macro_rules! file {() => {}} file!() "#, - BuiltinExpander::File, + BuiltinFnLikeExpander::File, ); assert_eq!(expanded, "\"\""); diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index e1d93a8ef..8e46fa177 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -9,14 +9,14 @@ use ra_prof::profile; use ra_syntax::{AstNode, Parse, SyntaxNode}; use crate::{ - ast_id_map::AstIdMap, BuiltinExpander, HirFileId, HirFileIdRepr, MacroCallId, MacroCallLoc, - MacroDefId, MacroDefKind, MacroFile, MacroFileKind, + ast_id_map::AstIdMap, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, + MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, MacroFileKind, }; #[derive(Debug, Clone, Eq, PartialEq)] pub enum TokenExpander { MacroRules(mbe::MacroRules), - Builtin(BuiltinExpander), + Builtin(BuiltinFnLikeExpander), } impl TokenExpander { diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index f514a15e4..4f3ccf1d0 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -24,7 +24,7 @@ use ra_syntax::{ }; use crate::ast_id_map::FileAstId; -use crate::builtin_macro::BuiltinExpander; +use crate::builtin_macro::BuiltinFnLikeExpander; #[cfg(test)] mod test_db; @@ -138,7 +138,7 @@ pub struct MacroDefId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum MacroDefKind { Declarative, - BuiltIn(BuiltinExpander), + BuiltIn(BuiltinFnLikeExpander), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -- cgit v1.2.3 From 16854e28ef1f2010d7d7d8e959a193fbcaeb5be8 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 23 Nov 2019 22:48:34 +0800 Subject: Use macro for all the things --- crates/ra_hir_expand/src/builtin_macro.rs | 79 ++++++++++++------------------- 1 file changed, 31 insertions(+), 48 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index a0069682d..c0e0436c0 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs @@ -8,29 +8,39 @@ use crate::{ use crate::quote; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum BuiltinFnLikeExpander { - Column, - File, - Line, - Stringify, -} - -struct BuiltInMacroInfo { - name: name::Name, - kind: BuiltinFnLikeExpander, - expand: fn( - db: &dyn AstDatabase, - id: MacroCallId, - _tt: &tt::Subtree, - ) -> Result, -} - macro_rules! register_builtin { ( $(($name:ident, $kind: ident) => $expand:ident),* ) => { - const BUILTIN_MACROS: &[BuiltInMacroInfo] = &[ - $(BuiltInMacroInfo { name: name::$name, kind: BuiltinFnLikeExpander::$kind, expand: $expand }),* - ]; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub enum BuiltinFnLikeExpander { + $($kind),* + } + + impl BuiltinFnLikeExpander { + pub fn expand( + &self, + db: &dyn AstDatabase, + id: MacroCallId, + tt: &tt::Subtree, + ) -> Result { + let expander = match *self { + $( BuiltinFnLikeExpander::$kind => $expand, )* + }; + expander(db, id, tt) + } + } + + pub fn find_builtin_macro( + ident: &name::Name, + krate: CrateId, + ast_id: AstId, + ) -> Option { + let kind = match ident { + $( id if id == &name::$name => BuiltinFnLikeExpander::$kind, )* + _ => return None, + }; + + Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(kind) }) + } }; } @@ -41,33 +51,6 @@ register_builtin! { (STRINGIFY_MACRO, Stringify) => stringify_expand } -impl BuiltinFnLikeExpander { - pub fn expand( - &self, - db: &dyn AstDatabase, - id: MacroCallId, - tt: &tt::Subtree, - ) -> Result { - let expander = BUILTIN_MACROS - .iter() - .find(|it| *self == it.kind) - .map(|it| it.expand) - .ok_or_else(|| mbe::ExpandError::ConversionError)?; - - expander(db, id, tt) - } -} - -pub fn find_builtin_macro( - ident: &name::Name, - krate: CrateId, - ast_id: AstId, -) -> Option { - let kind = BUILTIN_MACROS.iter().find(|it| *ident == it.name).map(|it| it.kind)?; - - Some(MacroDefId { krate, ast_id, kind: MacroDefKind::BuiltIn(kind) }) -} - fn to_line_number(db: &dyn AstDatabase, file: HirFileId, pos: TextUnit) -> usize { // FIXME: Use expansion info let file_id = file.original_file(db); -- cgit v1.2.3