mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
feat(config): Add a dedicated cached regex (#3832)
This commit is contained in:
parent
39e7f11c17
commit
efc67417a5
65
Cargo.lock
generated
65
Cargo.lock
generated
@ -60,9 +60,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.53"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
|
||||
checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
@ -643,6 +643,17 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0834a35a3fce649144119e18da2a4d8ed12ef3862f47183fd46f625d072d96c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"num_cpus",
|
||||
"parking_lot 0.12.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "debug_unreachable"
|
||||
version = "0.1.1"
|
||||
@ -1139,7 +1150,7 @@ name = "jsdoc"
|
||||
version = "0.60.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"nom 5.1.2",
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
@ -1917,7 +1928,7 @@ dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"browserslist-rs",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"from_variant",
|
||||
"once_cell",
|
||||
"semver 1.0.4",
|
||||
@ -2459,16 +2470,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_regex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.0"
|
||||
@ -2702,7 +2703,7 @@ dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"base64 0.13.0",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"either",
|
||||
"indexmap",
|
||||
"lru",
|
||||
@ -2717,6 +2718,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sourcemap",
|
||||
"swc_atoms",
|
||||
"swc_cached",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
@ -2757,7 +2759,7 @@ dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"crc",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"hex",
|
||||
"indexmap",
|
||||
"is-macro",
|
||||
@ -2794,6 +2796,19 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_cached"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"dashmap 5.1.0",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_cli"
|
||||
version = "0.13.0"
|
||||
@ -3040,7 +3055,7 @@ version = "0.19.1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"auto_impl",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"parking_lot 0.12.0",
|
||||
"rayon",
|
||||
"regex",
|
||||
@ -3062,15 +3077,15 @@ version = "0.28.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"lru",
|
||||
"normpath",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
"path-clean",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"swc_cached",
|
||||
"swc_common",
|
||||
"tracing",
|
||||
]
|
||||
@ -3092,8 +3107,8 @@ dependencies = [
|
||||
"retain_mut",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_regex",
|
||||
"swc_atoms",
|
||||
"swc_cached",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
@ -3139,7 +3154,7 @@ version = "0.98.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"preset_env_base",
|
||||
@ -3316,7 +3331,7 @@ name = "swc_ecma_transforms_optimization"
|
||||
version = "0.94.1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"rayon",
|
||||
@ -3368,7 +3383,7 @@ version = "0.86.2"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.13.0",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"regex",
|
||||
@ -3563,7 +3578,7 @@ name = "swc_node_bundler"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"is-macro",
|
||||
"once_cell",
|
||||
"pretty_assertions",
|
||||
@ -3592,7 +3607,7 @@ name = "swc_node_comments"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"dashmap",
|
||||
"dashmap 4.0.2",
|
||||
"swc_common",
|
||||
]
|
||||
|
||||
|
@ -40,12 +40,14 @@ either = "1"
|
||||
indexmap = {version = "1", features = ["serde"]}
|
||||
lru = "0.7.1"
|
||||
once_cell = "1.9.0"
|
||||
parking_lot = "0.12.0"
|
||||
pathdiff = "0.2.0"
|
||||
regex = "1"
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
serde_json = "1"
|
||||
sourcemap = "6"
|
||||
swc_atoms = {version = "0.2", path = "../swc_atoms"}
|
||||
swc_cached = {version = "0.1.0", path = "../swc_cached"}
|
||||
swc_common = {version = "0.17.0", path = "../swc_common", features = ["sourcemap", "concurrent", "parking_lot"]}
|
||||
swc_ecma_ast = {version = "0.68.0", path = "../swc_ecma_ast"}
|
||||
swc_ecma_codegen = {version = "0.93.0", path = "../swc_ecma_codegen"}
|
||||
@ -73,7 +75,6 @@ swc_node_comments = {version = "0.4.0", path = "../swc_node_comments"}
|
||||
swc_plugin_runner = {version = "0.38.0", path = "../swc_plugin_runner", optional = true}
|
||||
swc_visit = {version = "0.3.0", path = "../swc_visit"}
|
||||
tracing = "0.1.31"
|
||||
parking_lot = "0.12.0"
|
||||
|
||||
[dependencies.napi-derive]
|
||||
default-features = false
|
||||
|
@ -9,17 +9,17 @@ use std::{
|
||||
usize,
|
||||
};
|
||||
|
||||
use anyhow::{bail, Context, Error};
|
||||
use anyhow::{bail, Error};
|
||||
use dashmap::DashMap;
|
||||
use either::Either;
|
||||
use indexmap::IndexMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use serde::{
|
||||
de::{Unexpected, Visitor},
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_cached::regex::CachedRegex;
|
||||
pub use swc_common::chain;
|
||||
use swc_common::{
|
||||
collections::{AHashMap, AHashSet},
|
||||
@ -891,34 +891,23 @@ impl Config {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum FileMatcher {
|
||||
Regex(String),
|
||||
None,
|
||||
Regex(CachedRegex),
|
||||
Multi(Vec<FileMatcher>),
|
||||
}
|
||||
|
||||
impl Default for FileMatcher {
|
||||
fn default() -> Self {
|
||||
Self::Regex(String::from(""))
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
impl FileMatcher {
|
||||
pub fn matches(&self, filename: &Path) -> Result<bool, Error> {
|
||||
static CACHE: Lazy<DashMap<String, Regex, ahash::RandomState>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
match self {
|
||||
FileMatcher::Regex(ref s) => {
|
||||
if s.is_empty() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if !CACHE.contains_key(&*s) {
|
||||
let re = Regex::new(s).with_context(|| format!("invalid regex: {}", s))?;
|
||||
CACHE.insert(s.clone(), re);
|
||||
}
|
||||
|
||||
let re = CACHE.get(&*s).unwrap();
|
||||
FileMatcher::None => Ok(false),
|
||||
|
||||
FileMatcher::Regex(re) => {
|
||||
let filename = if cfg!(target_os = "windows") {
|
||||
filename.to_string_lossy().replace('\\', "/")
|
||||
} else {
|
||||
|
20
crates/swc_cached/Cargo.toml
Normal file
20
crates/swc_cached/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "Cached types for swc"
|
||||
documentation = "https://rustdoc.swc.rs/swc_cached/"
|
||||
edition = "2021"
|
||||
include = ["Cargo.toml", "src/**/*.rs"]
|
||||
license = "Apache-2.0"
|
||||
name = "swc_cached"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.1.0"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.7.6"
|
||||
anyhow = "1.0.55"
|
||||
dashmap = "5.1.0"
|
||||
once_cell = "1.9.0"
|
||||
regex = "1.5.4"
|
||||
serde = "1.0.136"
|
||||
swc_atoms = {version = "0.2.9", path = "../swc_atoms"}
|
3
crates/swc_cached/src/lib.rs
Normal file
3
crates/swc_cached/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
pub mod regex;
|
72
crates/swc_cached/src/regex.rs
Normal file
72
crates/swc_cached/src/regex.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use std::{ops::Deref, sync::Arc};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use dashmap::DashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use serde::{de::Error, Deserialize, Serialize};
|
||||
|
||||
/// A regex which can be used as a configuration.
|
||||
///
|
||||
/// While deserializing, this will be converted to a string and cached based on
|
||||
/// the pattern.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CachedRegex {
|
||||
regex: Arc<Regex>,
|
||||
}
|
||||
|
||||
impl Deref for CachedRegex {
|
||||
type Target = Regex;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.regex
|
||||
}
|
||||
}
|
||||
|
||||
impl CachedRegex {
|
||||
pub fn new(input: &str) -> Result<Self> {
|
||||
static CACHE: Lazy<DashMap<String, Arc<Regex>, ahash::RandomState>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
if let Some(cache) = CACHE.get(input).as_deref().cloned() {
|
||||
return Ok(Self { regex: cache });
|
||||
}
|
||||
|
||||
let regex =
|
||||
Regex::new(input).with_context(|| format!("failed to parse `{}` as regex", input))?;
|
||||
let regex = Arc::new(regex);
|
||||
|
||||
CACHE.insert(input.to_owned(), regex.clone());
|
||||
|
||||
Ok(CachedRegex { regex })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for CachedRegex {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
|
||||
Self::new(&s).map_err(|err| D::Error::custom(err.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for CachedRegex {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let s = self.regex.as_str();
|
||||
|
||||
serializer.serialize_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// This will panic for wrong patterns.
|
||||
impl From<&'_ str> for CachedRegex {
|
||||
fn from(s: &'_ str) -> Self {
|
||||
Self::new(s).unwrap()
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ cache = ["lru", "parking_lot"]
|
||||
# Enable node js resolver
|
||||
node = ["normpath", "serde_json", "dashmap", "once_cell", "path-clean"]
|
||||
# Enable support for `paths` of tsconfig.json
|
||||
tsc = ["dashmap", "once_cell", "regex"]
|
||||
tsc = ["dashmap", "once_cell", "swc_cached"]
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.7.4"
|
||||
@ -29,9 +29,9 @@ lru = {version = "0.7.1", optional = true}
|
||||
once_cell = {version = "1.9.0", optional = true}
|
||||
parking_lot = {version = "0.12.0", optional = true}
|
||||
path-clean = {version = "=0.1.0", optional = true}
|
||||
regex = {version = "1", optional = true}
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
serde_json = {version = "1.0.64", optional = true}
|
||||
swc_cached = {version = "0.1.0", optional = true, path = "../swc_cached"}
|
||||
swc_common = {version = "0.17.0", path = "../swc_common"}
|
||||
tracing = "0.1.31"
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
use std::path::{Component, PathBuf};
|
||||
|
||||
use anyhow::{bail, Context, Error};
|
||||
use dashmap::DashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use swc_cached::regex::CachedRegex;
|
||||
use swc_common::FileName;
|
||||
|
||||
use crate::resolve::Resolve;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Pattern {
|
||||
Regex(Regex),
|
||||
Regex(CachedRegex),
|
||||
/// No wildcard.
|
||||
Exact(String),
|
||||
}
|
||||
@ -193,19 +191,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_regex(src: String) -> Regex {
|
||||
static CACHE: Lazy<DashMap<String, Regex, ahash::RandomState>> = Lazy::new(Default::default);
|
||||
|
||||
if !CACHE.contains_key(&*src) {
|
||||
// Create capture group
|
||||
let regex_pat = src.replace('*', "(.*)");
|
||||
let re = Regex::new(®ex_pat).unwrap_or_else(|err| {
|
||||
panic!("failed to compile `{}` as a pattern: {:?}", regex_pat, err)
|
||||
});
|
||||
CACHE.insert(src.clone(), re);
|
||||
}
|
||||
|
||||
let re = CACHE.get(&*src).unwrap();
|
||||
|
||||
(*re).clone()
|
||||
fn compile_regex(src: String) -> CachedRegex {
|
||||
CachedRegex::new(&src.replace('*', "(.*)")).unwrap()
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ regex = "1.5.3"
|
||||
retain_mut = "0.1.2"
|
||||
serde = {version = "1.0.118", features = ["derive"]}
|
||||
serde_json = "1.0.61"
|
||||
serde_regex = "1.1.0"
|
||||
swc_atoms = {version = "0.2", path = "../swc_atoms"}
|
||||
swc_cached = {version = "0.1.0", path = "../swc_cached"}
|
||||
swc_common = {version = "0.17.0", path = "../swc_common"}
|
||||
swc_ecma_ast = {version = "0.68.0", path = "../swc_ecma_ast"}
|
||||
swc_ecma_codegen = {version = "0.93.0", path = "../swc_ecma_codegen"}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_cached::regex::CachedRegex;
|
||||
use swc_common::{collections::AHashMap, Mark};
|
||||
use swc_ecma_ast::{EsVersion, Expr};
|
||||
|
||||
@ -72,8 +72,8 @@ pub struct ManglePropertiesOptions {
|
||||
pub reserved: Vec<JsWord>,
|
||||
#[serde(default, alias = "undeclared")]
|
||||
pub undeclared: bool,
|
||||
#[serde(default, with = "serde_regex")]
|
||||
pub regex: Option<Regex>,
|
||||
#[serde(default)]
|
||||
pub regex: Option<CachedRegex>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
|
@ -2,15 +2,13 @@
|
||||
//!
|
||||
//! License is MIT, which is original license at the time of copying.
|
||||
//! Original test authors have copyright for their work.
|
||||
#![deny(warnings)]
|
||||
#![allow(clippy::needless_update)]
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use swc_common::{FileName, DUMMY_SP};
|
||||
use swc_css_ast::{
|
||||
ComponentValue, DeclarationOrAtRule, QualifiedRule, SimpleBlock, Stylesheet, Token,
|
||||
TokenAndSpan,
|
||||
};
|
||||
use swc_css_ast::{ComponentValue, DeclarationOrAtRule, QualifiedRule, SimpleBlock, Stylesheet};
|
||||
use swc_css_codegen::{
|
||||
writer::basic::{BasicCssWriter, BasicCssWriterConfig},
|
||||
CodegenConfig, Emit,
|
||||
@ -537,10 +535,10 @@ fn t(src: &str, expected: &str) {
|
||||
|
||||
wr.push_str(&s);
|
||||
|
||||
let need_semi = match p {
|
||||
ComponentValue::DeclarationOrAtRule(DeclarationOrAtRule::Invalid(_)) => false,
|
||||
_ => true,
|
||||
};
|
||||
let need_semi = !matches!(
|
||||
p,
|
||||
ComponentValue::DeclarationOrAtRule(DeclarationOrAtRule::Invalid(_))
|
||||
);
|
||||
|
||||
if need_semi {
|
||||
wr.push(';');
|
||||
|
Loading…
Reference in New Issue
Block a user