Skip to content

Commit b1594f1

Browse files
Merge #3727
3727: Introduce ra_proc_macro r=matklad a=edwin0cheng This PR implemented: 1. Reading dylib path of proc-macro crate from cargo check , similar to how `OUTDIR` is obtained. 2. Added a new crate `ra_proc_macro` and implement the foot-work for reading result from external proc-macro expander. 3. Added a struct `ProcMacroClient` , which will be responsible to the client side communication to the External process. Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
2 parents 20c110e + db162df commit b1594f1

File tree

20 files changed

+259
-38
lines changed

20 files changed

+259
-38
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_db/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ rustc-hash = "1.1.0"
1515
ra_syntax = { path = "../ra_syntax" }
1616
ra_cfg = { path = "../ra_cfg" }
1717
ra_prof = { path = "../ra_prof" }
18+
ra_tt = { path = "../ra_tt" }
1819
test_utils = { path = "../test_utils" }

crates/ra_db/src/fixture.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
7070
meta.cfg,
7171
meta.env,
7272
Default::default(),
73+
Default::default(),
7374
);
7475
crate_graph
7576
} else {
@@ -81,6 +82,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, ra_fixture: &str) -> FileId
8182
CfgOptions::default(),
8283
Env::default(),
8384
Default::default(),
85+
Default::default(),
8486
);
8587
crate_graph
8688
};
@@ -130,6 +132,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
130132
meta.cfg,
131133
meta.env,
132134
Default::default(),
135+
Default::default(),
133136
);
134137
let prev = crates.insert(krate.clone(), crate_id);
135138
assert!(prev.is_none());
@@ -167,6 +170,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
167170
CfgOptions::default(),
168171
Env::default(),
169172
Default::default(),
173+
Default::default(),
170174
);
171175
} else {
172176
for (from, to) in crate_deps {

crates/ra_db/src/input.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::{
1010
fmt, ops,
1111
path::{Path, PathBuf},
1212
str::FromStr,
13+
sync::Arc,
1314
};
1415

1516
use ra_cfg::CfgOptions;
@@ -19,6 +20,7 @@ use rustc_hash::FxHashSet;
1920

2021
use crate::{RelativePath, RelativePathBuf};
2122
use fmt::Display;
23+
use ra_tt::TokenExpander;
2224

2325
/// `FileId` is an integer which uniquely identifies a file. File paths are
2426
/// messy and system-dependent, so most of the code should work directly with
@@ -115,6 +117,22 @@ impl Display for CrateName {
115117
}
116118
}
117119

120+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
121+
pub struct ProcMacroId(pub u32);
122+
123+
#[derive(Debug, Clone)]
124+
pub struct ProcMacro {
125+
pub name: SmolStr,
126+
pub expander: Arc<dyn TokenExpander>,
127+
}
128+
129+
impl Eq for ProcMacro {}
130+
impl PartialEq for ProcMacro {
131+
fn eq(&self, other: &ProcMacro) -> bool {
132+
self.name == other.name && Arc::ptr_eq(&self.expander, &other.expander)
133+
}
134+
}
135+
118136
#[derive(Debug, Clone, PartialEq, Eq)]
119137
pub struct CrateData {
120138
pub root_file_id: FileId,
@@ -127,6 +145,7 @@ pub struct CrateData {
127145
pub env: Env,
128146
pub extern_source: ExternSource,
129147
pub dependencies: Vec<Dependency>,
148+
pub proc_macro: Vec<ProcMacro>,
130149
}
131150

132151
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -166,14 +185,19 @@ impl CrateGraph {
166185
cfg_options: CfgOptions,
167186
env: Env,
168187
extern_source: ExternSource,
188+
proc_macro: Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)>,
169189
) -> CrateId {
190+
let proc_macro =
191+
proc_macro.into_iter().map(|(name, it)| ProcMacro { name, expander: it }).collect();
192+
170193
let data = CrateData {
171194
root_file_id: file_id,
172195
edition,
173196
display_name,
174197
cfg_options,
175198
env,
176199
extern_source,
200+
proc_macro,
177201
dependencies: Vec::new(),
178202
};
179203
let crate_id = CrateId(self.arena.len() as u32);
@@ -345,6 +369,7 @@ mod tests {
345369
CfgOptions::default(),
346370
Env::default(),
347371
Default::default(),
372+
Default::default(),
348373
);
349374
let crate2 = graph.add_crate_root(
350375
FileId(2u32),
@@ -353,6 +378,7 @@ mod tests {
353378
CfgOptions::default(),
354379
Env::default(),
355380
Default::default(),
381+
Default::default(),
356382
);
357383
let crate3 = graph.add_crate_root(
358384
FileId(3u32),
@@ -361,6 +387,7 @@ mod tests {
361387
CfgOptions::default(),
362388
Env::default(),
363389
Default::default(),
390+
Default::default(),
364391
);
365392
assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
366393
assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
@@ -377,6 +404,7 @@ mod tests {
377404
CfgOptions::default(),
378405
Env::default(),
379406
Default::default(),
407+
Default::default(),
380408
);
381409
let crate2 = graph.add_crate_root(
382410
FileId(2u32),
@@ -385,6 +413,7 @@ mod tests {
385413
CfgOptions::default(),
386414
Env::default(),
387415
Default::default(),
416+
Default::default(),
388417
);
389418
let crate3 = graph.add_crate_root(
390419
FileId(3u32),
@@ -393,6 +422,7 @@ mod tests {
393422
CfgOptions::default(),
394423
Env::default(),
395424
Default::default(),
425+
Default::default(),
396426
);
397427
assert!(graph.add_dep(crate1, CrateName::new("crate2").unwrap(), crate2).is_ok());
398428
assert!(graph.add_dep(crate2, CrateName::new("crate3").unwrap(), crate3).is_ok());
@@ -408,6 +438,7 @@ mod tests {
408438
CfgOptions::default(),
409439
Env::default(),
410440
Default::default(),
441+
Default::default(),
411442
);
412443
let crate2 = graph.add_crate_root(
413444
FileId(2u32),
@@ -416,6 +447,7 @@ mod tests {
416447
CfgOptions::default(),
417448
Env::default(),
418449
Default::default(),
450+
Default::default(),
419451
);
420452
assert!(graph
421453
.add_dep(crate1, CrateName::normalize_dashes("crate-name-with-dashes"), crate2)

crates/ra_db/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use crate::{
1212
cancellation::Canceled,
1313
input::{
1414
CrateGraph, CrateId, CrateName, Dependency, Edition, Env, ExternSource, ExternSourceId,
15-
FileId, SourceRoot, SourceRootId,
15+
FileId, ProcMacroId, SourceRoot, SourceRootId,
1616
},
1717
};
1818
pub use relative_path::{RelativePath, RelativePathBuf};

crates/ra_hir_def/src/nameres/collector.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use hir_expand::{
1111
HirFileId, MacroCallId, MacroDefId, MacroDefKind,
1212
};
1313
use ra_cfg::CfgOptions;
14-
use ra_db::{CrateId, FileId};
14+
use ra_db::{CrateId, FileId, ProcMacroId};
1515
use ra_syntax::ast;
1616
use rustc_hash::FxHashMap;
1717
use test_utils::tested_by;
@@ -53,6 +53,16 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
5353
}
5454

5555
let cfg_options = &crate_graph[def_map.krate].cfg_options;
56+
let proc_macros = &crate_graph[def_map.krate].proc_macro;
57+
let proc_macros = proc_macros
58+
.iter()
59+
.enumerate()
60+
.map(|(idx, it)| {
61+
// FIXME: a hacky way to create a Name from string.
62+
let name = tt::Ident { text: it.name.clone(), id: tt::TokenId::unspecified() };
63+
(name.as_name(), ProcMacroExpander::new(def_map.krate, ProcMacroId(idx as u32)))
64+
})
65+
.collect();
5666

5767
let mut collector = DefCollector {
5868
db,
@@ -65,9 +75,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
6575
unexpanded_attribute_macros: Vec::new(),
6676
mod_dirs: FxHashMap::default(),
6777
cfg_options,
68-
69-
// FIXME: pass proc-macro from crate-graph
70-
proc_macros: Default::default(),
78+
proc_macros,
7179
};
7280
collector.collect();
7381
collector.finish()
Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,32 @@
11
//! Proc Macro Expander stub
22
3-
use crate::{db::AstDatabase, LazyMacroId, MacroCallKind, MacroCallLoc};
4-
use ra_db::CrateId;
3+
use crate::{db::AstDatabase, LazyMacroId};
4+
use ra_db::{CrateId, ProcMacroId};
55

66
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
77
pub struct ProcMacroExpander {
88
krate: CrateId,
9+
proc_macro_id: ProcMacroId,
910
}
1011

1112
impl ProcMacroExpander {
12-
pub fn new(krate: CrateId) -> ProcMacroExpander {
13-
ProcMacroExpander { krate }
13+
pub fn new(krate: CrateId, proc_macro_id: ProcMacroId) -> ProcMacroExpander {
14+
ProcMacroExpander { krate, proc_macro_id }
1415
}
1516

1617
pub fn expand(
1718
&self,
1819
db: &dyn AstDatabase,
19-
id: LazyMacroId,
20-
_tt: &tt::Subtree,
20+
_id: LazyMacroId,
21+
tt: &tt::Subtree,
2122
) -> Result<tt::Subtree, mbe::ExpandError> {
22-
let loc: MacroCallLoc = db.lookup_intern_macro(id);
23-
let name = match loc.kind {
24-
MacroCallKind::FnLike(_) => return Err(mbe::ExpandError::ConversionError),
25-
MacroCallKind::Attr(_, name) => name,
26-
};
23+
let krate_graph = db.crate_graph();
24+
let proc_macro = krate_graph[self.krate]
25+
.proc_macro
26+
.get(self.proc_macro_id.0 as usize)
27+
.clone()
28+
.ok_or_else(|| mbe::ExpandError::ConversionError)?;
2729

28-
log::debug!("Proc-macro-expanding name = {}", name);
29-
30-
// Return nothing for now
31-
return Ok(tt::Subtree::default());
30+
proc_macro.expander.expand(&tt, None).map_err(mbe::ExpandError::from)
3231
}
3332
}

crates/ra_ide/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ impl Analysis {
213213
cfg_options,
214214
Env::default(),
215215
Default::default(),
216+
Default::default(),
216217
);
217218
change.add_file(source_root, file_id, "main.rs".into(), Arc::new(text));
218219
change.set_crate_graph(crate_graph);

crates/ra_ide/src/mock_analysis.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ impl MockAnalysis {
103103
cfg_options,
104104
Env::default(),
105105
Default::default(),
106+
Default::default(),
106107
));
107108
} else if path.ends_with("/lib.rs") {
108109
let crate_name = path.parent().unwrap().file_name().unwrap();
@@ -113,6 +114,7 @@ impl MockAnalysis {
113114
cfg_options,
114115
Env::default(),
115116
Default::default(),
117+
Default::default(),
116118
);
117119
if let Some(root_crate) = root_crate {
118120
crate_graph

crates/ra_ide/src/parent_module.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ mod tests {
137137
CfgOptions::default(),
138138
Env::default(),
139139
Default::default(),
140+
Default::default(),
140141
);
141142
let mut change = AnalysisChange::new();
142143
change.set_crate_graph(crate_graph);

0 commit comments

Comments
 (0)