1pub mod clangd;
5pub mod symbols;
6pub mod rela;
7pub mod refs;
8pub mod srcs;
9pub mod cmdl;
10
11use async_std::task;
12
13use std::fs;
14use std::path::PathBuf;
15use std::collections::BTreeMap;
16use crate::symbols::SymbolKind;
17
18pub fn run(p: &PathBuf) -> clangd::ClangdDatabase {
20 let mut db = task::block_on(_run(p));
21 #[cfg(feature="post-process")]
22 post_process(&mut db);
23 db
24}
25
26#[cfg(feature="post-process")]
27fn post_process(db: &mut clangd::ClangdDatabase) {
28 for entry in db.name.iter() {
30 let sym = entry.1;
31
32 match sym.syminfo.kind {
33 SymbolKind::Variable => {
36 let decl_file = sym.canonical_declaration.file_uri.rsplit_once("/");
37 if decl_file.is_none() {
38 debug_assert!(false);
39 }
40 let decl_file = decl_file.unwrap().1;
41 if decl_file.ends_with(".h") {
42 let hfile = db.file.get_mut(&decl_file.to_string());
43 if hfile.is_none() {
44 debug_assert!(false);
45 }
46 let hfile = hfile.unwrap();
47 hfile.variable_declarations.push(sym.id.clone());
48 }
49 },
50 _ => ()
51 }
52 }
53}
54
55async fn _run(p: &PathBuf) -> clangd::ClangdDatabase {
56 let mut to_file: clangd::ClangdFileMap = BTreeMap::new();
57 let mut to_id: clangd::ClangdIdMap = BTreeMap::new();
58 let mut to_name: clangd::ClangdNameMap = BTreeMap::new();
59 let mut path = p.join(".cache");
60 if !path.exists() {
61 panic!("Unable to find .cache!");
62 }
63 path = path.join("clangd").join("index");
64 if !path.exists() {
65 panic!("Has clangd been run?");
66 }
67
68 let rd = fs::read_dir(path.as_path()).unwrap();
69 for entry in rd {
70 let e = entry.unwrap();
71 if e.file_type().unwrap().is_file() {
72 let _ret = clangd::ClangdFile::parse(e.path()).await;
73 if _ret.is_ok() {
74 let fname = e.file_name().to_str().unwrap().to_string();
75 let parts: Vec<&str> = fname.split(".").collect();
76 let fname = format!("{}.{}", parts[0], parts[1]);
77 let db = _ret.unwrap();
78 if !to_file.contains_key(&fname) {
79 let _ = to_file.insert(fname, db.clone());
80 }
81 for sym in db.symbols.data.iter() {
82 if !to_id.contains_key(&sym.id) {
83 let _ = to_id.insert(sym.id.clone(), sym.clone());
84 }
85 if !to_name.contains_key(&sym.name) {
86 let _ = to_name.insert(sym.name.clone(), sym.clone());
87 }
88 }
89 }
90 }
91 }
92
93 clangd::ClangdDatabase{ file: to_file, id: to_id, name: to_name }
94}