From cc6689534323ad0f142250ed553fb6469ff34bb3 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Thu, 21 Sep 2023 00:52:50 -0400 Subject: [PATCH] perf: cache the current language configuration to lookup later on --- Cargo.toml | 4 +++ cli/loader/src/lib.rs | 64 +++++++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 03e24caf..bc2aedaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,7 @@ codegen-units = 1 # Maximum size reduction optimizations. [profile.size] inherits = "release" opt-level = "s" # Optimize for size. + +[profile.profile] +inherits = "release" +strip = false diff --git a/cli/loader/src/lib.rs b/cli/loader/src/lib.rs index d260a96c..ed9c5f39 100644 --- a/cli/loader/src/lib.rs +++ b/cli/loader/src/lib.rs @@ -70,12 +70,12 @@ impl Config { } #[cfg(unix)] -const DYLIB_EXTENSION: &'static str = "so"; +const DYLIB_EXTENSION: &str = "so"; #[cfg(windows)] const DYLIB_EXTENSION: &'static str = "dll"; -const BUILD_TARGET: &'static str = env!("BUILD_TARGET"); +const BUILD_TARGET: &str = env!("BUILD_TARGET"); pub struct LanguageConfiguration<'a> { pub scope: Option, @@ -101,6 +101,7 @@ pub struct Loader { languages_by_id: Vec<(PathBuf, OnceCell)>, language_configurations: Vec>, language_configuration_ids_by_file_type: HashMap>, + language_configuration_in_current_path: Option, highlight_names: Box>>, use_all_highlight_names: bool, debug_build: bool, @@ -127,13 +128,14 @@ impl Loader { languages_by_id: Vec::new(), language_configurations: Vec::new(), language_configuration_ids_by_file_type: HashMap::new(), + language_configuration_in_current_path: None, highlight_names: Box::new(Mutex::new(Vec::new())), use_all_highlight_names: true, debug_build: false, } } - pub fn configure_highlights(&mut self, names: &Vec) { + pub fn configure_highlights(&mut self, names: &[String]) { self.use_all_highlight_names = false; let mut highlights = self.highlight_names.lock().unwrap(); highlights.clear(); @@ -149,8 +151,7 @@ impl Loader { eprintln!("Warning: You have not configured any parser directories!"); eprintln!("Please run `tree-sitter init-config` and edit the resulting"); eprintln!("configuration file to indicate where we should look for"); - eprintln!("language grammars."); - eprintln!(""); + eprintln!("language grammars.\n"); } for parser_container_dir in &config.parser_directories { if let Ok(entries) = fs::read_dir(parser_container_dir) { @@ -160,6 +161,7 @@ impl Loader { if parser_dir_name.starts_with("tree-sitter-") { self.find_language_configurations_at_path( &parser_container_dir.join(parser_dir_name), + false, ) .ok(); } @@ -171,7 +173,7 @@ impl Loader { } pub fn languages_at_path(&mut self, path: &Path) -> Result> { - if let Ok(configurations) = self.find_language_configurations_at_path(path) { + if let Ok(configurations) = self.find_language_configurations_at_path(path, true) { let mut language_ids = configurations .iter() .map(|c| c.language_id) @@ -342,7 +344,7 @@ impl Loader { self.load_language_from_sources( &grammar_json.name, - &header_path, + header_path, &parser_path, scanner_path.as_deref(), ) @@ -362,7 +364,7 @@ impl Loader { let mut library_path = self.parser_lib_path.join(lib_name); library_path.set_extension(DYLIB_EXTENSION); - let recompile = needs_recompile(&library_path, &parser_path, scanner_path) + let recompile = needs_recompile(&library_path, parser_path, scanner_path) .with_context(|| "Failed to compare source and binary timestamps")?; if recompile { @@ -382,7 +384,7 @@ impl Loader { } if compiler.is_like_msvc() { - command.args(&["/nologo", "/LD", "/I"]).arg(header_path); + command.args(["/nologo", "/LD", "/I"]).arg(header_path); if self.debug_build { command.arg("/Od"); } else { @@ -514,24 +516,20 @@ impl Loader { } } - pub fn find_language_configurations_at_path<'a>( - &'a mut self, + pub fn find_language_configurations_at_path( + &mut self, parser_path: &Path, + set_current_path_config: bool, ) -> Result<&[LanguageConfiguration]> { - #[derive(Deserialize)] + #[derive(Default, Deserialize)] #[serde(untagged)] enum PathsJSON { + #[default] Empty, Single(String), Multiple(Vec), } - impl Default for PathsJSON { - fn default() -> Self { - PathsJSON::Empty - } - } - impl PathsJSON { fn into_vec(self) -> Option> { match self { @@ -614,7 +612,7 @@ impl Loader { let configuration = LanguageConfiguration { root_path: parser_path.to_path_buf(), - language_name: grammar_json.name, + language_name: grammar_json.name.clone(), scope: config_json.scope, language_id, file_types: config_json.file_types.unwrap_or(Vec::new()), @@ -627,19 +625,26 @@ impl Loader { highlights_filenames: config_json.highlights.into_vec(), highlight_config: OnceCell::new(), tags_config: OnceCell::new(), - highlight_names: &*self.highlight_names, + highlight_names: &self.highlight_names, use_all_highlight_names: self.use_all_highlight_names, }; for file_type in &configuration.file_types { self.language_configuration_ids_by_file_type .entry(file_type.to_string()) - .or_insert(Vec::new()) + .or_default() .push(self.language_configurations.len()); } self.language_configurations .push(unsafe { mem::transmute(configuration) }); + + if set_current_path_config + && self.language_configuration_in_current_path.is_none() + { + self.language_configuration_in_current_path = + Some(self.language_configurations.len() - 1); + } } } } @@ -668,7 +673,7 @@ impl Loader { tags_filenames: None, highlight_config: OnceCell::new(), tags_config: OnceCell::new(), - highlight_names: &*self.highlight_names, + highlight_names: &self.highlight_names, use_all_highlight_names: self.use_all_highlight_names, }; self.language_configurations @@ -693,11 +698,11 @@ impl Loader { if let Some(scope) = scope { if let Some(config) = self .language_configuration_for_scope(scope) - .with_context(|| format!("Failed to load language for scope '{}'", scope))? + .with_context(|| format!("Failed to load language for scope '{scope}'"))? { Ok(config.0) } else { - return Err(anyhow!("Unknown scope '{}'", scope)); + Err(anyhow!("Unknown scope '{scope}'")) } } else if let Some((lang, _)) = self .language_configuration_for_file_name(path) @@ -709,8 +714,10 @@ impl Loader { })? { Ok(lang) + } else if let Some(id) = self.language_configuration_in_current_path { + Ok(self.language_for_id(self.language_configurations[id].language_id)?) } else if let Some(lang) = self - .languages_at_path(¤t_dir) + .languages_at_path(current_dir) .with_context(|| "Failed to load language in current directory")? .first() .cloned() @@ -833,7 +840,7 @@ impl<'a> LanguageConfiguration<'a> { } } } - result.configure(&all_highlight_names.as_slice()); + result.configure(all_highlight_names.as_slice()); Ok(Some(result)) } }) @@ -869,7 +876,6 @@ impl<'a> LanguageConfiguration<'a> { locals_query.len(), ) } - .into() } else { error.into() } @@ -879,9 +885,9 @@ impl<'a> LanguageConfiguration<'a> { .map(Option::as_ref) } - fn include_path_in_query_error<'b>( + fn include_path_in_query_error( mut error: QueryError, - ranges: &'b Vec<(String, Range)>, + ranges: &[(String, Range)], source: &str, start_offset: usize, ) -> Error {