From 48059b72a84602a007bb102d57496e43da7a876f Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Mon, 20 Jan 2025 19:44:59 -0500 Subject: [PATCH] feat: remove `lazy_static` in favor of `LazyLock` This switches to the built-in `std::sync::LazyLock` --- Cargo.lock | 10 --- Cargo.toml | 1 - cli/Cargo.toml | 1 - cli/benches/benchmark.rs | 94 ++++++++++++----------- cli/generate/Cargo.toml | 1 - cli/generate/src/build_tables/item.rs | 33 ++++---- cli/generate/src/lib.rs | 10 +-- cli/loader/Cargo.toml | 1 - cli/loader/src/lib.rs | 7 +- cli/src/fuzz/mod.rs | 34 ++++++--- cli/src/highlight.rs | 9 +-- cli/src/query_testing.rs | 7 +- cli/src/test.rs | 37 +++++---- cli/src/tests/helpers/dirs.rs | 106 +++++++++++++++----------- cli/src/tests/helpers/fixtures.rs | 18 ++--- cli/src/tests/highlight_test.rs | 50 +++++++----- cli/src/tests/query_test.rs | 8 +- cli/src/tests/wasm_language_test.rs | 7 +- highlight/Cargo.toml | 1 - highlight/src/lib.rs | 14 ++-- 20 files changed, 234 insertions(+), 215 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2f4028f..7c72f4b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1016,12 +1016,6 @@ dependencies = [ "libc", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "leb128" version = "0.2.5" @@ -1925,7 +1919,6 @@ dependencies = [ "html-escape", "indexmap", "indoc", - "lazy_static", "log", "memchr", "pretty_assertions", @@ -1975,7 +1968,6 @@ dependencies = [ "heck", "indexmap", "indoc", - "lazy_static", "log", "regex", "regex-syntax", @@ -1993,7 +1985,6 @@ dependencies = [ name = "tree-sitter-highlight" version = "0.25.0" dependencies = [ - "lazy_static", "regex", "streaming-iterator", "thiserror 2.0.11", @@ -2013,7 +2004,6 @@ dependencies = [ "etcetera", "fs4", "indoc", - "lazy_static", "libloading", "once_cell", "path-slash", diff --git a/Cargo.toml b/Cargo.toml index bc7aae7a..c579773e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,7 +118,6 @@ heck = "0.5.0" html-escape = "0.2.13" indexmap = "2.7.1" indoc = "2.0.5" -lazy_static = "1.5.0" libloading = "0.8.6" log = { version = "0.4.25", features = ["std"] } memchr = "2.7.4" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 64aa95be..d1c6172b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -43,7 +43,6 @@ heck.workspace = true html-escape.workspace = true indexmap.workspace = true indoc.workspace = true -lazy_static.workspace = true log.workspace = true memchr.workspace = true rand.workspace = true diff --git a/cli/benches/benchmark.rs b/cli/benches/benchmark.rs index 7d6cc2fb..2b0e29ea 100644 --- a/cli/benches/benchmark.rs +++ b/cli/benches/benchmark.rs @@ -3,68 +3,72 @@ use std::{ env, fs, path::{Path, PathBuf}, str, + sync::LazyLock, time::Instant, }; use anyhow::Context; -use lazy_static::lazy_static; use tree_sitter::{Language, Parser, Query}; use tree_sitter_loader::{CompileConfig, Loader}; include!("../src/tests/helpers/dirs.rs"); -lazy_static! { - static ref LANGUAGE_FILTER: Option = - env::var("TREE_SITTER_BENCHMARK_LANGUAGE_FILTER").ok(); - static ref EXAMPLE_FILTER: Option = - env::var("TREE_SITTER_BENCHMARK_EXAMPLE_FILTER").ok(); - static ref REPETITION_COUNT: usize = env::var("TREE_SITTER_BENCHMARK_REPETITION_COUNT") +static LANGUAGE_FILTER: LazyLock> = + LazyLock::new(|| env::var("TREE_SITTER_BENCHMARK_LANGUAGE_FILTER").ok()); +static EXAMPLE_FILTER: LazyLock> = + LazyLock::new(|| env::var("TREE_SITTER_BENCHMARK_EXAMPLE_FILTER").ok()); +static REPETITION_COUNT: LazyLock = LazyLock::new(|| { + env::var("TREE_SITTER_BENCHMARK_REPETITION_COUNT") .map(|s| s.parse::().unwrap()) - .unwrap_or(5); - static ref TEST_LOADER: Loader = Loader::with_parser_lib_path(SCRATCH_DIR.clone()); - static ref EXAMPLE_AND_QUERY_PATHS_BY_LANGUAGE_DIR: BTreeMap, Vec)> = { - fn process_dir(result: &mut BTreeMap, Vec)>, dir: &Path) { - if dir.join("grammar.js").exists() { - let relative_path = dir.strip_prefix(GRAMMARS_DIR.as_path()).unwrap(); - let (example_paths, query_paths) = - result.entry(relative_path.to_owned()).or_default(); + .unwrap_or(5) +}); +static TEST_LOADER: LazyLock = + LazyLock::new(|| Loader::with_parser_lib_path(SCRATCH_DIR.clone())); - if let Ok(example_files) = fs::read_dir(dir.join("examples")) { - example_paths.extend(example_files.filter_map(|p| { - let p = p.unwrap().path(); - if p.is_file() { - Some(p) - } else { - None - } - })); - } +#[allow(clippy::type_complexity)] +static EXAMPLE_AND_QUERY_PATHS_BY_LANGUAGE_DIR: LazyLock< + BTreeMap, Vec)>, +> = LazyLock::new(|| { + fn process_dir(result: &mut BTreeMap, Vec)>, dir: &Path) { + if dir.join("grammar.js").exists() { + let relative_path = dir.strip_prefix(GRAMMARS_DIR.as_path()).unwrap(); + let (example_paths, query_paths) = result.entry(relative_path.to_owned()).or_default(); - if let Ok(query_files) = fs::read_dir(dir.join("queries")) { - query_paths.extend(query_files.filter_map(|p| { - let p = p.unwrap().path(); - if p.is_file() { - Some(p) - } else { - None - } - })); - } - } else { - for entry in fs::read_dir(dir).unwrap() { - let entry = entry.unwrap().path(); - if entry.is_dir() { - process_dir(result, &entry); + if let Ok(example_files) = fs::read_dir(dir.join("examples")) { + example_paths.extend(example_files.filter_map(|p| { + let p = p.unwrap().path(); + if p.is_file() { + Some(p) + } else { + None } + })); + } + + if let Ok(query_files) = fs::read_dir(dir.join("queries")) { + query_paths.extend(query_files.filter_map(|p| { + let p = p.unwrap().path(); + if p.is_file() { + Some(p) + } else { + None + } + })); + } + } else { + for entry in fs::read_dir(dir).unwrap() { + let entry = entry.unwrap().path(); + if entry.is_dir() { + process_dir(result, &entry); } } } + } - let mut result = BTreeMap::new(); - process_dir(&mut result, &GRAMMARS_DIR); - result - }; -} + let mut result = BTreeMap::new(); + process_dir(&mut result, &GRAMMARS_DIR); + result +}); fn main() { let max_path_length = EXAMPLE_AND_QUERY_PATHS_BY_LANGUAGE_DIR diff --git a/cli/generate/Cargo.toml b/cli/generate/Cargo.toml index e1170891..7955a79c 100644 --- a/cli/generate/Cargo.toml +++ b/cli/generate/Cargo.toml @@ -20,7 +20,6 @@ anyhow.workspace = true heck.workspace = true indexmap.workspace = true indoc.workspace = true -lazy_static.workspace = true log.workspace = true regex.workspace = true regex-syntax.workspace = true diff --git a/cli/generate/src/build_tables/item.rs b/cli/generate/src/build_tables/item.rs index 57c598e4..12d71641 100644 --- a/cli/generate/src/build_tables/item.rs +++ b/cli/generate/src/build_tables/item.rs @@ -2,10 +2,9 @@ use std::{ cmp::Ordering, fmt, hash::{Hash, Hasher}, + sync::LazyLock, }; -use lazy_static::lazy_static; - use crate::{ grammars::{ LexicalGrammar, Production, ProductionStep, ReservedWordSetId, SyntaxGrammar, @@ -14,22 +13,20 @@ use crate::{ rules::{Associativity, Precedence, Symbol, SymbolType, TokenSet}, }; -lazy_static! { - static ref START_PRODUCTION: Production = Production { - dynamic_precedence: 0, - steps: vec![ProductionStep { - symbol: Symbol { - index: 0, - kind: SymbolType::NonTerminal, - }, - precedence: Precedence::None, - associativity: None, - alias: None, - field_name: None, - reserved_word_set_id: NO_RESERVED_WORDS, - }], - }; -} +static START_PRODUCTION: LazyLock = LazyLock::new(|| Production { + dynamic_precedence: 0, + steps: vec![ProductionStep { + symbol: Symbol { + index: 0, + kind: SymbolType::NonTerminal, + }, + precedence: Precedence::None, + associativity: None, + alias: None, + field_name: None, + reserved_word_set_id: NO_RESERVED_WORDS, + }], +}); /// A [`ParseItem`] represents an in-progress match of a single production in a grammar. #[derive(Clone, Copy, Debug)] diff --git a/cli/generate/src/lib.rs b/cli/generate/src/lib.rs index 89d68a5b..9fdb15db 100644 --- a/cli/generate/src/lib.rs +++ b/cli/generate/src/lib.rs @@ -3,12 +3,12 @@ use std::{ io::Write, path::{Path, PathBuf}, process::{Command, Stdio}, + sync::LazyLock, }; use anyhow::Result; use build_tables::build_tables; use grammars::InputGrammar; -use lazy_static::lazy_static; pub use node_types::VariableInfoError; use parse_grammar::parse_grammar; pub use parse_grammar::ParseGrammarError; @@ -34,12 +34,12 @@ pub use build_tables::ParseTableBuilderError; use serde::Serialize; use thiserror::Error; -lazy_static! { - static ref JSON_COMMENT_REGEX: Regex = RegexBuilder::new("^\\s*//.*") +static JSON_COMMENT_REGEX: LazyLock = LazyLock::new(|| { + RegexBuilder::new("^\\s*//.*") .multi_line(true) .build() - .unwrap(); -} + .unwrap() +}); struct GeneratedParser { c_code: String, diff --git a/cli/loader/Cargo.toml b/cli/loader/Cargo.toml index fc534b9a..e42274d9 100644 --- a/cli/loader/Cargo.toml +++ b/cli/loader/Cargo.toml @@ -29,7 +29,6 @@ cc.workspace = true etcetera.workspace = true fs4.workspace = true indoc.workspace = true -lazy_static.workspace = true libloading.workspace = true once_cell.workspace = true path-slash.workspace = true diff --git a/cli/loader/src/lib.rs b/cli/loader/src/lib.rs index 6ed817c6..0edaff0e 100644 --- a/cli/loader/src/lib.rs +++ b/cli/loader/src/lib.rs @@ -14,6 +14,7 @@ use std::{ mem, path::{Path, PathBuf}, process::Command, + sync::LazyLock, time::SystemTime, }; @@ -23,7 +24,6 @@ use anyhow::{anyhow, Context, Result}; use etcetera::BaseStrategy as _; use fs4::fs_std::FileExt; use indoc::indoc; -use lazy_static::lazy_static; use libloading::{Library, Symbol}; use once_cell::unsync::OnceCell; use path_slash::PathBufExt as _; @@ -41,9 +41,8 @@ use tree_sitter_highlight::HighlightConfiguration; use tree_sitter_tags::{Error as TagsError, TagsConfiguration}; use url::Url; -lazy_static! { - static ref GRAMMAR_NAME_REGEX: Regex = Regex::new(r#""name":\s*"(.*?)""#).unwrap(); -} +static GRAMMAR_NAME_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r#""name":\s*"(.*?)""#).unwrap()); pub const EMSCRIPTEN_TAG: &str = concat!("docker.io/emscripten/emsdk:", env!("EMSCRIPTEN_VERSION")); diff --git a/cli/src/fuzz/mod.rs b/cli/src/fuzz/mod.rs index 38993e1f..85e219cc 100644 --- a/cli/src/fuzz/mod.rs +++ b/cli/src/fuzz/mod.rs @@ -1,6 +1,5 @@ -use std::{collections::HashMap, env, fs, path::Path}; +use std::{collections::HashMap, env, fs, path::Path, sync::LazyLock}; -use lazy_static::lazy_static; use rand::Rng; use regex::Regex; use tree_sitter::{Language, Parser}; @@ -23,16 +22,27 @@ use crate::{ test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields, TestEntry}, }; -lazy_static! { - pub static ref LOG_ENABLED: bool = env::var("TREE_SITTER_LOG").is_ok(); - pub static ref LOG_GRAPH_ENABLED: bool = env::var("TREE_SITTER_LOG_GRAPHS").is_ok(); - pub static ref LANGUAGE_FILTER: Option = env::var("TREE_SITTER_LANGUAGE").ok(); - pub static ref EXAMPLE_INCLUDE: Option = regex_env_var("TREE_SITTER_EXAMPLE_INCLUDE"); - pub static ref EXAMPLE_EXCLUDE: Option = regex_env_var("TREE_SITTER_EXAMPLE_EXCLUDE"); - pub static ref START_SEED: usize = new_seed(); - pub static ref EDIT_COUNT: usize = int_env_var("TREE_SITTER_EDITS").unwrap_or(3); - pub static ref ITERATION_COUNT: usize = int_env_var("TREE_SITTER_ITERATIONS").unwrap_or(10); -} +pub static LOG_ENABLED: LazyLock = LazyLock::new(|| env::var("TREE_SITTER_LOG").is_ok()); + +pub static LOG_GRAPH_ENABLED: LazyLock = + LazyLock::new(|| env::var("TREE_SITTER_LOG_GRAPHS").is_ok()); + +pub static LANGUAGE_FILTER: LazyLock> = + LazyLock::new(|| env::var("TREE_SITTER_LANGUAGE").ok()); + +pub static EXAMPLE_INCLUDE: LazyLock> = + LazyLock::new(|| regex_env_var("TREE_SITTER_EXAMPLE_INCLUDE")); + +pub static EXAMPLE_EXCLUDE: LazyLock> = + LazyLock::new(|| regex_env_var("TREE_SITTER_EXAMPLE_EXCLUDE")); + +pub static START_SEED: LazyLock = LazyLock::new(new_seed); + +pub static EDIT_COUNT: LazyLock = + LazyLock::new(|| int_env_var("TREE_SITTER_EDITS").unwrap_or(3)); + +pub static ITERATION_COUNT: LazyLock = + LazyLock::new(|| int_env_var("TREE_SITTER_ITERATIONS").unwrap_or(10)); fn int_env_var(name: &'static str) -> Option { env::var(name).ok().and_then(|e| e.parse().ok()) diff --git a/cli/src/highlight.rs b/cli/src/highlight.rs index 20364b53..cfdd2f76 100644 --- a/cli/src/highlight.rs +++ b/cli/src/highlight.rs @@ -5,13 +5,12 @@ use std::{ io::{self, Write as _}, path::{self, Path, PathBuf}, str, - sync::{atomic::AtomicUsize, Arc}, + sync::{atomic::AtomicUsize, Arc, LazyLock}, time::Instant, }; use anstyle::{Ansi256Color, AnsiColor, Color, Effects, RgbColor}; use anyhow::Result; -use lazy_static::lazy_static; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{json, Value}; use tree_sitter_highlight::{HighlightConfiguration, HighlightEvent, Highlighter, HtmlRenderer}; @@ -45,10 +44,8 @@ pub const HTML_FOOTER: &str = " "; -lazy_static! { - static ref CSS_STYLES_BY_COLOR_ID: Vec = - serde_json::from_str(include_str!("../vendor/xterm-colors.json")).unwrap(); -} +static CSS_STYLES_BY_COLOR_ID: LazyLock> = + LazyLock::new(|| serde_json::from_str(include_str!("../vendor/xterm-colors.json")).unwrap()); #[derive(Debug, Default)] pub struct Style { diff --git a/cli/src/query_testing.rs b/cli/src/query_testing.rs index 3774abdf..289591f0 100644 --- a/cli/src/query_testing.rs +++ b/cli/src/query_testing.rs @@ -1,14 +1,11 @@ -use std::{fs, path::Path}; +use std::{fs, path::Path, sync::LazyLock}; use anyhow::{anyhow, Result}; use bstr::{BStr, ByteSlice}; -use lazy_static::lazy_static; use regex::Regex; use tree_sitter::{Language, Parser, Point}; -lazy_static! { - static ref CAPTURE_NAME_REGEX: Regex = Regex::new("[\\w_\\-.]+").unwrap(); -} +static CAPTURE_NAME_REGEX: LazyLock = LazyLock::new(|| Regex::new("[\\w_\\-.]+").unwrap()); #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Utf8Point { diff --git a/cli/src/test.rs b/cli/src/test.rs index f278de99..e128bc80 100644 --- a/cli/src/test.rs +++ b/cli/src/test.rs @@ -6,6 +6,7 @@ use std::{ io::{self, Write}, path::{Path, PathBuf}, str, + sync::LazyLock, time::Duration, }; @@ -13,7 +14,6 @@ use anstyle::{AnsiColor, Color, Style}; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; use indoc::indoc; -use lazy_static::lazy_static; use regex::{ bytes::{Regex as ByteRegex, RegexBuilder as ByteRegexBuilder}, Regex, @@ -25,29 +25,36 @@ use walkdir::WalkDir; use super::util; use crate::parse::Stats; -lazy_static! { - static ref HEADER_REGEX: ByteRegex = ByteRegexBuilder::new( +static HEADER_REGEX: LazyLock = LazyLock::new(|| { + ByteRegexBuilder::new( r"^(?x) (?P(?:=+){3,}) (?P[^=\r\n][^\r\n]*)? \r?\n (?P(?:([^=\r\n]|\s+:)[^\r\n]*\r?\n)+) ===+ - (?P[^=\r\n][^\r\n]*)?\r?\n" + (?P[^=\r\n][^\r\n]*)?\r?\n", ) .multi_line(true) .build() - .unwrap(); - static ref DIVIDER_REGEX: ByteRegex = - ByteRegexBuilder::new(r"^(?P(?:-+){3,})(?P[^-\r\n][^\r\n]*)?\r?\n") - .multi_line(true) - .build() - .unwrap(); - static ref COMMENT_REGEX: Regex = Regex::new(r"(?m)^\s*;.*$").unwrap(); - static ref WHITESPACE_REGEX: Regex = Regex::new(r"\s+").unwrap(); - static ref SEXP_FIELD_REGEX: Regex = Regex::new(r" \w+: \(").unwrap(); - static ref POINT_REGEX: Regex = Regex::new(r"\s*\[\s*\d+\s*,\s*\d+\s*\]\s*").unwrap(); -} + .unwrap() +}); + +static DIVIDER_REGEX: LazyLock = LazyLock::new(|| { + ByteRegexBuilder::new(r"^(?P(?:-+){3,})(?P[^-\r\n][^\r\n]*)?\r?\n") + .multi_line(true) + .build() + .unwrap() +}); + +static COMMENT_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"(?m)^\s*;.*$").unwrap()); + +static WHITESPACE_REGEX: LazyLock = LazyLock::new(|| Regex::new(r"\s+").unwrap()); + +static SEXP_FIELD_REGEX: LazyLock = LazyLock::new(|| Regex::new(r" \w+: \(").unwrap()); + +static POINT_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"\s*\[\s*\d+\s*,\s*\d+\s*\]\s*").unwrap()); #[derive(Debug, PartialEq, Eq)] pub enum TestEntry { diff --git a/cli/src/tests/helpers/dirs.rs b/cli/src/tests/helpers/dirs.rs index 4d1c4982..22e99588 100644 --- a/cli/src/tests/helpers/dirs.rs +++ b/cli/src/tests/helpers/dirs.rs @@ -1,47 +1,63 @@ -lazy_static! { - pub static ref ROOT_DIR: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR")).parent().unwrap().to_owned(); - pub static ref FIXTURES_DIR: PathBuf = ROOT_DIR.join("test").join("fixtures"); - pub static ref HEADER_DIR: PathBuf = ROOT_DIR.join("lib").join("include"); - pub static ref GRAMMARS_DIR: PathBuf = ROOT_DIR.join("test").join("fixtures").join("grammars"); - pub static ref SCRATCH_BASE_DIR: PathBuf = { - let result = ROOT_DIR.join("target").join("scratch"); - fs::create_dir_all(&result).unwrap(); - result - }; - pub static ref WASM_DIR: PathBuf = ROOT_DIR.join("target").join("release"); - pub static ref SCRATCH_DIR: PathBuf = { - // https://doc.rust-lang.org/reference/conditional-compilation.html - let vendor = if cfg!(target_vendor = "apple") { - "apple" - } else if cfg!(target_vendor = "fortanix") { - "fortanix" - } else if cfg!(target_vendor = "pc") { - "pc" - } else { - "unknown" - }; - let env = if cfg!(target_env = "gnu") { - "gnu" - } else if cfg!(target_env = "msvc") { - "msvc" - } else if cfg!(target_env = "musl") { - "musl" - } else if cfg!(target_env = "sgx") { - "sgx" - } else { - "unknown" - }; - let endian = if cfg!(target_endian = "little") { - "little" - } else if cfg!(target_endian = "big") { - "big" - } else { - "unknown" - }; +pub static ROOT_DIR: LazyLock = LazyLock::new(|| { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .unwrap() + .to_owned() +}); - let machine = format!("{}-{}-{vendor}-{env}-{endian}", std::env::consts::ARCH, std::env::consts::OS); - let result = SCRATCH_BASE_DIR.join(machine); - fs::create_dir_all(&result).unwrap(); - result +pub static FIXTURES_DIR: LazyLock = + LazyLock::new(|| ROOT_DIR.join("test").join("fixtures")); + +pub static HEADER_DIR: LazyLock = LazyLock::new(|| ROOT_DIR.join("lib").join("include")); + +pub static GRAMMARS_DIR: LazyLock = + LazyLock::new(|| ROOT_DIR.join("test").join("fixtures").join("grammars")); + +pub static SCRATCH_BASE_DIR: LazyLock = LazyLock::new(|| { + let result = ROOT_DIR.join("target").join("scratch"); + fs::create_dir_all(&result).unwrap(); + result +}); + +#[cfg(feature = "wasm")] +pub static WASM_DIR: LazyLock = LazyLock::new(|| ROOT_DIR.join("target").join("release")); + +pub static SCRATCH_DIR: LazyLock = LazyLock::new(|| { + // https://doc.rust-lang.org/reference/conditional-compilation.html + let vendor = if cfg!(target_vendor = "apple") { + "apple" + } else if cfg!(target_vendor = "fortanix") { + "fortanix" + } else if cfg!(target_vendor = "pc") { + "pc" + } else { + "unknown" }; -} + let env = if cfg!(target_env = "gnu") { + "gnu" + } else if cfg!(target_env = "msvc") { + "msvc" + } else if cfg!(target_env = "musl") { + "musl" + } else if cfg!(target_env = "sgx") { + "sgx" + } else { + "unknown" + }; + let endian = if cfg!(target_endian = "little") { + "little" + } else if cfg!(target_endian = "big") { + "big" + } else { + "unknown" + }; + + let machine = format!( + "{}-{}-{vendor}-{env}-{endian}", + std::env::consts::ARCH, + std::env::consts::OS + ); + let result = SCRATCH_BASE_DIR.join(machine); + fs::create_dir_all(&result).unwrap(); + result +}); diff --git a/cli/src/tests/helpers/fixtures.rs b/cli/src/tests/helpers/fixtures.rs index 943d7cf3..44da9b48 100644 --- a/cli/src/tests/helpers/fixtures.rs +++ b/cli/src/tests/helpers/fixtures.rs @@ -1,10 +1,10 @@ use std::{ env, fs, path::{Path, PathBuf}, + sync::LazyLock, }; use anyhow::Context; -use lazy_static::lazy_static; use tree_sitter::Language; use tree_sitter_generate::{ALLOC_HEADER, ARRAY_HEADER}; use tree_sitter_highlight::HighlightConfiguration; @@ -13,15 +13,13 @@ use tree_sitter_tags::TagsConfiguration; include!("./dirs.rs"); -lazy_static! { - static ref TEST_LOADER: Loader = { - let mut loader = Loader::with_parser_lib_path(SCRATCH_DIR.clone()); - if env::var("TREE_SITTER_GRAMMAR_DEBUG").is_ok() { - loader.debug_build(true); - } - loader - }; -} +static TEST_LOADER: LazyLock = LazyLock::new(|| { + let mut loader = Loader::with_parser_lib_path(SCRATCH_DIR.clone()); + if env::var("TREE_SITTER_GRAMMAR_DEBUG").is_ok() { + loader.debug_build(true); + } + loader +}); pub fn test_loader() -> &'static Loader { &TEST_LOADER diff --git a/cli/src/tests/highlight_test.rs b/cli/src/tests/highlight_test.rs index b8a0ea28..8d7ff7b3 100644 --- a/cli/src/tests/highlight_test.rs +++ b/cli/src/tests/highlight_test.rs @@ -3,31 +3,40 @@ use std::{ fs, os::raw::c_char, ptr, slice, str, - sync::atomic::{AtomicUsize, Ordering}, + sync::{ + atomic::{AtomicUsize, Ordering}, + LazyLock, + }, }; -use lazy_static::lazy_static; use tree_sitter_highlight::{ c, Error, Highlight, HighlightConfiguration, HighlightEvent, Highlighter, HtmlRenderer, }; use super::helpers::fixtures::{get_highlight_config, get_language, get_language_queries_path}; -lazy_static! { - static ref JS_HIGHLIGHT: HighlightConfiguration = - get_highlight_config("javascript", Some("injections.scm"), &HIGHLIGHT_NAMES); - static ref JSDOC_HIGHLIGHT: HighlightConfiguration = - get_highlight_config("jsdoc", None, &HIGHLIGHT_NAMES); - static ref HTML_HIGHLIGHT: HighlightConfiguration = - get_highlight_config("html", Some("injections.scm"), &HIGHLIGHT_NAMES); - static ref EJS_HIGHLIGHT: HighlightConfiguration = get_highlight_config( +static JS_HIGHLIGHT: LazyLock = + LazyLock::new(|| get_highlight_config("javascript", Some("injections.scm"), &HIGHLIGHT_NAMES)); + +static JSDOC_HIGHLIGHT: LazyLock = + LazyLock::new(|| get_highlight_config("jsdoc", None, &HIGHLIGHT_NAMES)); + +static HTML_HIGHLIGHT: LazyLock = + LazyLock::new(|| get_highlight_config("html", Some("injections.scm"), &HIGHLIGHT_NAMES)); + +static EJS_HIGHLIGHT: LazyLock = LazyLock::new(|| { + get_highlight_config( "embedded-template", Some("injections-ejs.scm"), - &HIGHLIGHT_NAMES - ); - static ref RUST_HIGHLIGHT: HighlightConfiguration = - get_highlight_config("rust", Some("injections.scm"), &HIGHLIGHT_NAMES); - static ref HIGHLIGHT_NAMES: Vec = [ + &HIGHLIGHT_NAMES, + ) +}); + +static RUST_HIGHLIGHT: LazyLock = + LazyLock::new(|| get_highlight_config("rust", Some("injections.scm"), &HIGHLIGHT_NAMES)); + +static HIGHLIGHT_NAMES: LazyLock> = LazyLock::new(|| { + [ "attribute", "boolean", "carriage-return", @@ -60,12 +69,15 @@ lazy_static! { .iter() .copied() .map(String::from) - .collect(); - static ref HTML_ATTRS: Vec = HIGHLIGHT_NAMES + .collect() +}); + +static HTML_ATTRS: LazyLock> = LazyLock::new(|| { + HIGHLIGHT_NAMES .iter() .map(|s| format!("class={s}")) - .collect(); -} + .collect() +}); #[test] fn test_highlighting_javascript() { diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index 9a002ae8..6f5e7077 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -1,7 +1,6 @@ -use std::{env, fmt::Write}; +use std::{env, fmt::Write, sync::LazyLock}; use indoc::indoc; -use lazy_static::lazy_static; use rand::{prelude::StdRng, SeedableRng}; use streaming_iterator::StreamingIterator; use tree_sitter::{ @@ -22,9 +21,8 @@ use crate::tests::{ ITERATION_COUNT, }; -lazy_static! { - static ref EXAMPLE_FILTER: Option = env::var("TREE_SITTER_TEST_EXAMPLE_FILTER").ok(); -} +static EXAMPLE_FILTER: LazyLock> = + LazyLock::new(|| env::var("TREE_SITTER_TEST_EXAMPLE_FILTER").ok()); #[test] fn test_query_errors_on_invalid_syntax() { diff --git a/cli/src/tests/wasm_language_test.rs b/cli/src/tests/wasm_language_test.rs index 34584dae..dcf8c193 100644 --- a/cli/src/tests/wasm_language_test.rs +++ b/cli/src/tests/wasm_language_test.rs @@ -1,6 +1,5 @@ -use std::fs; +use std::{fs, sync::LazyLock}; -use lazy_static::lazy_static; use streaming_iterator::StreamingIterator; use tree_sitter::{ wasmtime::Engine, Parser, Query, QueryCursor, WasmError, WasmErrorKind, WasmStore, @@ -8,9 +7,7 @@ use tree_sitter::{ use crate::tests::helpers::{allocations, fixtures::WASM_DIR}; -lazy_static! { - static ref ENGINE: Engine = Engine::default(); -} +static ENGINE: LazyLock = LazyLock::new(Engine::default); #[test] fn test_wasm_stdlib_symbols() { diff --git a/highlight/Cargo.toml b/highlight/Cargo.toml index c6f0063c..f48789f1 100644 --- a/highlight/Cargo.toml +++ b/highlight/Cargo.toml @@ -22,7 +22,6 @@ workspace = true crate-type = ["lib", "staticlib"] [dependencies] -lazy_static.workspace = true regex.workspace = true thiserror.workspace = true streaming-iterator.workspace = true diff --git a/highlight/src/lib.rs b/highlight/src/lib.rs index 56ce2d04..3998502f 100644 --- a/highlight/src/lib.rs +++ b/highlight/src/lib.rs @@ -8,11 +8,13 @@ use std::{ marker::PhantomData, mem::{self, MaybeUninit}, ops, str, - sync::atomic::{AtomicUsize, Ordering}, + sync::{ + atomic::{AtomicUsize, Ordering}, + LazyLock, + }, }; pub use c_lib as c; -use lazy_static::lazy_static; use streaming_iterator::StreamingIterator; use thiserror::Error; use tree_sitter::{ @@ -24,8 +26,8 @@ const CANCELLATION_CHECK_INTERVAL: usize = 100; const BUFFER_HTML_RESERVE_CAPACITY: usize = 10 * 1024; const BUFFER_LINES_RESERVE_CAPACITY: usize = 1000; -lazy_static! { - static ref STANDARD_CAPTURE_NAMES: HashSet<&'static str> = vec![ +static STANDARD_CAPTURE_NAMES: LazyLock> = LazyLock::new(|| { + vec![ "attribute", "boolean", "carriage-return", @@ -80,8 +82,8 @@ lazy_static! { "variable.parameter", ] .into_iter() - .collect(); -} + .collect() +}); /// Indicates which highlight should be applied to a region of source code. #[derive(Copy, Clone, Debug, PartialEq, Eq)]