Skip to content

Commit e1af664

Browse files
committed
Fast references impl
1 parent 6d95909 commit e1af664

File tree

20 files changed

+324
-147
lines changed

20 files changed

+324
-147
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ codegen-sdk-resolution = { workspace = true}
2020
sysinfo = "0.33.1"
2121
rkyv.workspace = true
2222
[features]
23-
python = [ "codegen-sdk-analyzer/python", "codegen-sdk-python"] # TODO: Add python support
23+
python = [ "codegen-sdk-analyzer/python", "codegen-sdk-python"]
2424
typescript = [ "codegen-sdk-analyzer/typescript", "codegen-sdk-typescript"]
2525
tsx = [ "codegen-sdk-analyzer/tsx"]
2626
jsx = [ "codegen-sdk-analyzer/jsx"]

codegen-sdk-analyzer/src/codebase.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,14 @@ impl Codebase {
8888
pub fn execute_op_with_progress<T: Send + Sync>(
8989
&self,
9090
name: &str,
91-
op: fn(&dyn Db, File) -> T,
91+
parallel: bool,
92+
op: fn(&dyn Db, codegen_sdk_common::FileNodeId<'_>) -> T,
9293
) -> Vec<T> {
9394
execute_op_with_progress(
9495
self._db(),
9596
codegen_sdk_resolution::files(self._db()),
9697
name,
98+
parallel,
9799
op,
98100
)
99101
}
@@ -118,8 +120,9 @@ impl CodebaseContext for Codebase {
118120
fn get_file<'a>(&'a self, path: PathBuf) -> Option<&'a Self::File<'a>> {
119121
if let Ok(path) = path.canonicalize() {
120122
let file = self.db.files.get(&path);
121-
if let Some(file) = file {
122-
return parse_file(&self.db, file.clone()).file(&self.db).as_ref();
123+
if let Some(_) = file {
124+
let file_id = codegen_sdk_common::FileNodeId::new(&self.db, path);
125+
return parse_file(&self.db, file_id).file(&self.db).as_ref();
123126
}
124127
}
125128
None

codegen-sdk-analyzer/src/codebase/parser.rs

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1+
use std::path::PathBuf;
2+
13
use codegen_sdk_ast::{Definitions, References};
24
#[cfg(feature = "serialization")]
35
use codegen_sdk_common::serialize::Cache;
4-
use codegen_sdk_cst::File;
56
use codegen_sdk_resolution::{Db, Scope};
67
use indicatif::{ProgressBar, ProgressStyle};
78

89
use super::discovery::{FilesToParse, log_languages};
910
use crate::{ParsedFile, database::CodegenDatabase, parser::parse_file};
10-
pub fn execute_op_with_progress<Database: Db + ?Sized + 'static, T: Send + Sync>(
11+
pub fn execute_op_with_progress<
12+
Database: Db + ?Sized + 'static,
13+
Input: Send + Sync,
14+
T: Send + Sync,
15+
>(
1116
db: &Database,
12-
files: codegen_sdk_common::hash::FxHashSet<File>,
17+
files: codegen_sdk_common::hash::FxHashSet<Input>,
1318
name: &str,
14-
op: fn(&Database, File) -> T,
19+
parallel: bool,
20+
op: fn(&Database, Input) -> T,
1521
) -> Vec<T> {
1622
let multi = db.multi_progress();
1723
let style = ProgressStyle::with_template(
@@ -27,19 +33,35 @@ pub fn execute_op_with_progress<Database: Db + ?Sized + 'static, T: Send + Sync>
2733
.into_iter()
2834
.map(|file| (&pg, file, op))
2935
.collect::<Vec<_>>();
30-
let results: Vec<T> = salsa::par_map(db, inputs, move |db, input| {
31-
let (pg, file, op) = input;
32-
let res = op(
33-
db,
34-
#[cfg(feature = "serialization")]
35-
&cache,
36-
file,
37-
);
38-
pg.inc(1);
39-
res
40-
});
36+
let results: Vec<_> = if parallel {
37+
salsa::par_map(db, inputs, move |db, input| {
38+
let (pg, file, op) = input;
39+
let res = op(
40+
db,
41+
#[cfg(feature = "serialization")]
42+
&cache,
43+
file,
44+
);
45+
pg.inc(1);
46+
res
47+
})
48+
} else {
49+
inputs
50+
.into_iter()
51+
.map(|input| {
52+
let (pg, file, op) = input;
53+
let res = op(
54+
db,
55+
#[cfg(feature = "serialization")]
56+
&cache,
57+
file,
58+
);
59+
pg.inc(1);
60+
res
61+
})
62+
.collect()
63+
};
4164
pg.finish();
42-
multi.remove(&pg);
4365
results
4466
}
4567
// #[salsa::tracked]
@@ -50,7 +72,12 @@ pub fn execute_op_with_progress<Database: Db + ?Sized + 'static, T: Send + Sync>
5072
// }
5173
#[salsa::tracked]
5274
fn parse_files_definitions_par(db: &dyn Db, files: FilesToParse) {
53-
let _: Vec<_> = execute_op_with_progress(db, files.files(db), "Parsing Files", |db, input| {
75+
let ids = files
76+
.files(db)
77+
.iter()
78+
.map(|input| codegen_sdk_common::FileNodeId::new(db, input.path(db)))
79+
.collect::<codegen_sdk_common::hash::FxHashSet<_>>();
80+
let _: Vec<_> = execute_op_with_progress(db, ids, "Parsing Files", true, |db, input| {
5481
let file = parse_file(db, input.clone());
5582
if let Some(parsed) = file.file(db) {
5683
#[cfg(feature = "typescript")]
@@ -62,12 +89,47 @@ fn parse_files_definitions_par(db: &dyn Db, files: FilesToParse) {
6289
if let ParsedFile::Python(parsed) = parsed {
6390
parsed.definitions(db);
6491
parsed.references(db);
65-
codegen_sdk_python::ast::dependencies(db, input);
92+
// let deps = codegen_sdk_python::ast::dependencies(db, input);
93+
// for dep in deps.dependencies(db).keys() {
94+
// codegen_sdk_resolution::ast::references_impl(db, dep);
95+
// }
6696
}
6797
}
6898
()
6999
});
70100
}
101+
#[salsa::tracked]
102+
fn compute_dependencies_par(db: &dyn Db, files: FilesToParse) {
103+
let ids = files
104+
.files(db)
105+
.iter()
106+
.map(|input| codegen_sdk_common::FileNodeId::new(db, input.path(db)))
107+
.collect::<codegen_sdk_common::hash::FxHashSet<_>>();
108+
let targets: codegen_sdk_common::hash::FxHashSet<(PathBuf, String)> =
109+
execute_op_with_progress(db, ids, "Computing Dependencies", true, |db, input| {
110+
let file = parse_file(db, input.clone());
111+
if let Some(parsed) = file.file(db) {
112+
#[cfg(feature = "python")]
113+
if let ParsedFile::Python(parsed) = parsed {
114+
let deps = codegen_sdk_python::ast::dependency_keys(db, input);
115+
return deps
116+
.iter()
117+
.map(|dep| (dep.path(db).path(db).clone(), dep.name(db).clone()))
118+
.collect::<Vec<_>>();
119+
}
120+
}
121+
Vec::new()
122+
})
123+
.into_iter()
124+
.flatten()
125+
.collect();
126+
// let _: Vec<_> = execute_op_with_progress(db, targets, "Finding Usages", true, |db, input: (PathBuf, String)| {
127+
// let file_node_id = codegen_sdk_common::FileNodeId::new(db, input.0);
128+
// let fully_qualified_name = codegen_sdk_resolution::FullyQualifiedName::new(db, file_node_id, input.1);
129+
// codegen_sdk_python::ast::references_impl(db, fully_qualified_name);
130+
// });
131+
}
132+
71133
pub fn parse_files<'db>(
72134
db: &'db CodegenDatabase,
73135
#[cfg(feature = "serialization")] cache: &'db Cache,
@@ -89,6 +151,12 @@ pub fn parse_files<'db>(
89151
&cache,
90152
files_to_parse,
91153
);
154+
compute_dependencies_par(
155+
db,
156+
#[cfg(feature = "serialization")]
157+
&cache,
158+
files_to_parse,
159+
);
92160
#[cfg(feature = "serialization")]
93161
report_cached_count(cached, &files_to_parse.files(db));
94162
}

codegen-sdk-analyzer/src/database.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::progress::get_multi_progress;
2020
// Basic Database implementation for Query generation. This is not used for anything else.
2121
pub struct CodegenDatabase {
2222
storage: salsa::Storage<Self>,
23-
pub files: DashMap<PathBuf, File>,
23+
pub files: Arc<DashMap<PathBuf, File>>,
2424
dirs: Vec<PathBuf>,
2525
multi_progress: MultiProgress,
2626
file_watcher: Arc<Mutex<Debouncer<RecommendedWatcher>>>,
@@ -41,7 +41,7 @@ impl CodegenDatabase {
4141
file_watcher: get_watcher(tx),
4242
storage: salsa::Storage::default(),
4343
multi_progress,
44-
files: DashMap::new(),
44+
files: Arc::new(DashMap::new()),
4545
dirs: Vec::new(),
4646
root,
4747
}
@@ -72,10 +72,10 @@ impl salsa::Database for CodegenDatabase {
7272
}
7373
#[salsa::db]
7474
impl Db for CodegenDatabase {
75-
fn files(&self) -> codegen_sdk_common::hash::FxHashSet<codegen_sdk_cst::File> {
75+
fn files(&self) -> codegen_sdk_common::hash::FxHashSet<codegen_sdk_common::FileNodeId<'_>> {
7676
self.files
7777
.iter()
78-
.map(|entry| entry.value().clone())
78+
.map(|entry| codegen_sdk_common::FileNodeId::new(self, entry.key().clone()))
7979
.collect()
8080
}
8181
fn watch_dir(&mut self, path: PathBuf) -> anyhow::Result<()> {

codegen-sdk-analyzer/src/parser.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ pub struct Parsed<'db> {
1414
pub file: Option<ParsedFile<'db>>,
1515
}
1616
#[salsa::tracked(return_ref)]
17-
pub fn parse_file(db: &dyn salsa::Database, file: codegen_sdk_cst::File) -> Parsed<'_> {
17+
pub fn parse_file<'db>(
18+
db: &'db dyn codegen_sdk_resolution::Db,
19+
file: codegen_sdk_common::FileNodeId<'db>,
20+
) -> Parsed<'db> {
1821
parse_language!();
19-
Parsed::new(db, FileNodeId::new(db, file.path(db)), None)
22+
Parsed::new(db, file, None)
2023
}

codegen-sdk-ast-generator/src/generator.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn generate_ast(language: &Language) -> anyhow::Result<TokenStream> {
7272
pub id: codegen_sdk_common::FileNodeId<'db>,
7373
}
7474
impl<'db> codegen_sdk_resolution::Parse<'db> for #language_struct_name<'db> {
75-
fn parse(db: &'db dyn salsa::Database, input: codegen_sdk_cst::File) -> &'db Self {
75+
fn parse(db: &'db dyn codegen_sdk_resolution::Db, input: codegen_sdk_common::FileNodeId<'db>) -> &'db Self {
7676
parse(db, input)
7777
}
7878
}
@@ -82,7 +82,8 @@ pub fn generate_ast(language: &Language) -> anyhow::Result<TokenStream> {
8282
// }}
8383
// }}
8484
#[salsa::tracked(return_ref)]
85-
pub fn parse(db: &dyn salsa::Database, input: codegen_sdk_cst::File) -> #language_struct_name<'_> {
85+
pub fn parse<'db>(db: &'db dyn codegen_sdk_resolution::Db, input: codegen_sdk_common::FileNodeId<'db>) -> #language_struct_name<'db> {
86+
let input = db.input(input.path(db)).unwrap();
8687
log::debug!("Parsing {} file: {}", input.path(db).display(), #language_name_str);
8788
let ast = crate::cst::parse_program_raw(db, input);
8889
let file_id = codegen_sdk_common::FileNodeId::new(db, input.path(db).clone());

codegen-sdk-ast-generator/src/query.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ impl<'a> Query<'a> {
662662
let symbol_name = self.symbol_name();
663663
return quote! {
664664
let fully_qualified_name = codegen_sdk_resolution::FullyQualifiedName::new(db, node.file_id(),#name.source());
665-
let symbol = #symbol_name::new(db, fully_qualified_name, id, node.clone(), #(#args.clone().into()),*);
665+
let symbol = #symbol_name::new(db, fully_qualified_name, id, #(#args.clone().into()),*);
666666
#to_append.entry(#name.source()).or_default().push(symbol);
667667
};
668668
}
@@ -913,6 +913,8 @@ impl<'a> Query<'a> {
913913
}
914914
let name_ident = format_ident!("{}", name);
915915
fields.push(parse_quote!(
916+
#[tracked]
917+
#[return_ref]
916918
pub #name_ident: crate::cst::#type_name<'db>
917919
));
918920
}

codegen-sdk-ast-generator/src/visitor.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,30 @@ pub fn generate_visitor<'db>(
8484
_fully_qualified_name: codegen_sdk_resolution::FullyQualifiedName<'db>,
8585
#[id]
8686
node_id: indextree::NodeId,
87-
#[tracked]
88-
#[return_ref]
89-
pub node: crate::cst::#type_name<'db>,
87+
// #[tracked]
88+
// #[return_ref]
89+
// pub node: crate::cst::#type_name<'db>,
9090
#(#fields),*
9191
}
92+
impl<'db> #variant<'db> {
93+
pub fn node(&self, db: &'db dyn codegen_sdk_resolution::Db) -> &'db crate::cst::#type_name<'db> {
94+
let file = self.file(db);
95+
let tree = file.tree(db);
96+
tree.get(&self.node_id(db)).unwrap().as_ref().try_into().unwrap()
97+
}
98+
}
9299
impl<'db> codegen_sdk_resolution::HasFile<'db> for #variant<'db> {
93100
type File<'db1> = #language_struct<'db1>;
94101
fn file(&self, db: &'db dyn codegen_sdk_resolution::Db) -> &'db Self::File<'db> {
95-
let path = self.node(db).id().file(db).path(db);
96-
let input = db.get_file(path).unwrap();
97-
parse(db, input)
102+
let path = self._fully_qualified_name(db).path(db);
103+
parse(db, path)
98104
}
99-
fn root_path(&self, db: &'db dyn salsa::Database) -> PathBuf {
105+
fn root_path(&self, db: &'db dyn codegen_sdk_resolution::Db) -> PathBuf {
100106
self.node(db).id().root(db).path(db)
101107
}
102108
}
103109
impl<'db> codegen_sdk_resolution::HasId<'db> for #variant<'db> {
104-
fn fully_qualified_name(&self, db: &'db dyn codegen_sdk_resolution::Db) -> codegen_sdk_resolution::FullyQualifiedName<'db> {
110+
fn fully_qualified_name(&self, db: &'db dyn salsa::Database) -> codegen_sdk_resolution::FullyQualifiedName<'db> {
105111
self._fully_qualified_name(db)
106112
}
107113
}
@@ -125,14 +131,14 @@ pub fn generate_visitor<'db>(
125131
#(Self::#symbol_names(symbol) => symbol.file(db),)*
126132
}
127133
}
128-
fn root_path(&self, db: &'db dyn salsa::Database) -> PathBuf {
134+
fn root_path(&self, db: &'db dyn codegen_sdk_resolution::Db) -> PathBuf {
129135
match self {
130136
#(Self::#symbol_names(symbol) => symbol.root_path(db),)*
131137
}
132138
}
133139
}
134140
impl<'db> codegen_sdk_resolution::HasId<'db> for #symbol_name<'db> {
135-
fn fully_qualified_name(&self, db: &'db dyn codegen_sdk_resolution::Db) -> codegen_sdk_resolution::FullyQualifiedName<'db> {
141+
fn fully_qualified_name(&self, db: &'db dyn salsa::Database) -> codegen_sdk_resolution::FullyQualifiedName<'db> {
136142
match self {
137143
#(Self::#symbol_names(symbol) => symbol.fully_qualified_name(db),)*
138144
}

codegen-sdk-common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ salsa = { workspace = true }
4141
indextree = { workspace = true }
4242
indexmap = { workspace = true }
4343
rustc-hash = "2.1.1"
44+
hashbrown = { version = "0.15.2", features = ["rayon"] }
4445
[dev-dependencies]
4546
test-log = { workspace = true }
4647
[features]

0 commit comments

Comments
 (0)