mirror of
https://github.com/swc-project/swc.git
synced 2024-10-04 04:07:18 +03:00
refactor(preset-env): Extract common logic for browserslist
support (#3674)
This commit is contained in:
parent
8012056bd8
commit
b1d24702e3
4
.github/workflows/cargo.yml
vendored
4
.github/workflows/cargo.yml
vendored
@ -84,6 +84,8 @@ jobs:
|
||||
# Use scripts/github/create-matrix.sh to create this.
|
||||
- crate: ast_node
|
||||
os: ubuntu-latest
|
||||
- crate: better_scoped_tls
|
||||
os: ubuntu-latest
|
||||
- crate: enum_kind
|
||||
os: ubuntu-latest
|
||||
- crate: from_variant
|
||||
@ -94,6 +96,8 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
- crate: node_macro_deps
|
||||
os: ubuntu-latest
|
||||
- crate: preset_env_base
|
||||
os: ubuntu-latest
|
||||
- crate: string_enum
|
||||
os: ubuntu-latest
|
||||
- crate: swc
|
||||
|
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1852,6 +1852,21 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "preset_env_base"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"browserslist-rs",
|
||||
"dashmap",
|
||||
"from_variant",
|
||||
"once_cell",
|
||||
"semver 1.0.4",
|
||||
"serde",
|
||||
"st-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "0.7.2"
|
||||
@ -3040,10 +3055,10 @@ version = "0.93.2"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"browserslist-rs",
|
||||
"dashmap",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"preset_env_base",
|
||||
"pretty_assertions",
|
||||
"semver 1.0.4",
|
||||
"serde",
|
||||
|
21
crates/preset_env_base/Cargo.toml
Normal file
21
crates/preset_env_base/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "Common logic for targetting vairous browsers"
|
||||
documentation = "https://rustdoc.swc.rs/preset_env_base/"
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
name = "preset_env_base"
|
||||
version = "0.1.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.7.4"
|
||||
anyhow = "1"
|
||||
browserslist-rs = "=0.8.0"
|
||||
dashmap = "4.0.2"
|
||||
from_variant = {version = "0.1.3", path = "../from_variant"}
|
||||
once_cell = "1.9.0"
|
||||
semver = {version = "1.0.4", features = ["serde"]}
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
st-map = "0.1.2"
|
99
crates/preset_env_base/src/lib.rs
Normal file
99
crates/preset_env_base/src/lib.rs
Normal file
@ -0,0 +1,99 @@
|
||||
use anyhow::Error;
|
||||
use serde::Deserialize;
|
||||
use st_map::StaticMap;
|
||||
|
||||
use self::version::Version;
|
||||
|
||||
pub mod query;
|
||||
pub mod version;
|
||||
|
||||
/// A map without allocation.
|
||||
#[derive(Debug, Default, Deserialize, Clone, Copy, StaticMap)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BrowserData<T: Default> {
|
||||
#[serde(default)]
|
||||
pub chrome: T,
|
||||
#[serde(default)]
|
||||
pub and_chr: T,
|
||||
#[serde(default)]
|
||||
pub and_ff: T,
|
||||
#[serde(default)]
|
||||
pub op_mob: T,
|
||||
#[serde(default)]
|
||||
pub ie: T,
|
||||
#[serde(default)]
|
||||
pub edge: T,
|
||||
#[serde(default)]
|
||||
pub firefox: T,
|
||||
#[serde(default)]
|
||||
pub safari: T,
|
||||
#[serde(default)]
|
||||
pub node: T,
|
||||
#[serde(default)]
|
||||
pub ios: T,
|
||||
#[serde(default)]
|
||||
pub samsung: T,
|
||||
#[serde(default)]
|
||||
pub opera: T,
|
||||
#[serde(default)]
|
||||
pub android: T,
|
||||
#[serde(default)]
|
||||
pub electron: T,
|
||||
#[serde(default)]
|
||||
pub phantom: T,
|
||||
#[serde(default)]
|
||||
pub opera_mobile: T,
|
||||
#[serde(default)]
|
||||
pub rhino: T,
|
||||
}
|
||||
|
||||
pub type Versions = BrowserData<Option<Version>>;
|
||||
|
||||
impl BrowserData<Option<Version>> {
|
||||
pub fn is_any_target(&self) -> bool {
|
||||
self.iter().all(|(_, v)| v.is_none())
|
||||
}
|
||||
|
||||
pub fn parse_versions(distribs: Vec<browserslist::Distrib>) -> Result<Self, Error> {
|
||||
fn remap(key: &str) -> &str {
|
||||
match key {
|
||||
"and_chr" => "chrome",
|
||||
"and_ff" => "firefox",
|
||||
"ie_mob" => "ie",
|
||||
"ios_saf" => "ios",
|
||||
"op_mob" => "opera",
|
||||
_ => key,
|
||||
}
|
||||
}
|
||||
|
||||
let mut data: Versions = BrowserData::default();
|
||||
for dist in distribs {
|
||||
let browser = dist.name();
|
||||
let browser = remap(browser);
|
||||
let version = dist.version();
|
||||
match &*browser {
|
||||
"and_qq" | "and_uc" | "baidu" | "bb" | "kaios" | "op_mini" => continue,
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let version = version
|
||||
.split_once('-')
|
||||
.map(|(version, _)| version)
|
||||
.unwrap_or(version)
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
// lowest version
|
||||
if data[&browser].map(|v| v > version).unwrap_or(true) {
|
||||
for (k, v) in data.iter_mut() {
|
||||
if browser == k {
|
||||
*v = Some(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
140
crates/preset_env_base/src/query.rs
Normal file
140
crates/preset_env_base/src/query.rs
Normal file
@ -0,0 +1,140 @@
|
||||
#![deny(clippy::all)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::{Context, Error};
|
||||
use dashmap::DashMap;
|
||||
use from_variant::FromVariant;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{version::Version, BrowserData, Versions};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant)]
|
||||
#[serde(untagged)]
|
||||
pub enum Targets {
|
||||
Query(Query),
|
||||
EsModules(EsModules),
|
||||
Versions(Versions),
|
||||
/// This uses `ahash` directly to reduce build time.
|
||||
///
|
||||
/// This type is identical to `swc_common::collections::AHashMap`
|
||||
HashMap(HashMap<String, QueryOrVersion, ahash::RandomState>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
||||
pub struct EsModules {
|
||||
#[allow(dead_code)]
|
||||
esmodules: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant)]
|
||||
#[serde(untagged)]
|
||||
pub enum QueryOrVersion {
|
||||
Query(Query),
|
||||
Version(Version),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
#[serde(untagged)]
|
||||
pub enum Query {
|
||||
Single(String),
|
||||
Multiple(Vec<String>),
|
||||
}
|
||||
|
||||
type QueryResult = Result<Versions, Error>;
|
||||
|
||||
impl Query {
|
||||
fn exec(&self) -> QueryResult {
|
||||
fn query<T>(s: &[T]) -> QueryResult
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let distribs = browserslist::resolve(
|
||||
s,
|
||||
browserslist::Opts::new()
|
||||
.mobile_to_desktop(true)
|
||||
.ignore_unknown_versions(true),
|
||||
)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to resolve browserslist query: {:?}",
|
||||
s.iter().map(|v| v.as_ref()).collect::<Vec<_>>()
|
||||
)
|
||||
})?;
|
||||
|
||||
let versions =
|
||||
BrowserData::parse_versions(distribs).expect("failed to parse browser version");
|
||||
|
||||
Ok(versions)
|
||||
}
|
||||
|
||||
static CACHE: Lazy<DashMap<Query, Versions, ahash::RandomState>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
if let Some(v) = CACHE.get(self) {
|
||||
return Ok(*v);
|
||||
}
|
||||
|
||||
let result = match *self {
|
||||
Query::Single(ref s) => {
|
||||
if s.is_empty() {
|
||||
query(&["defaults"])
|
||||
} else {
|
||||
query(&[s])
|
||||
}
|
||||
}
|
||||
Query::Multiple(ref s) => query(s),
|
||||
}
|
||||
.context("failed to execute query")?;
|
||||
|
||||
CACHE.insert(self.clone(), result);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn targets_to_versions(v: Option<Targets>) -> Result<Versions, Error> {
|
||||
match v {
|
||||
None => Ok(Default::default()),
|
||||
Some(Targets::Versions(v)) => Ok(v),
|
||||
Some(Targets::Query(q)) => q
|
||||
.exec()
|
||||
.context("failed to convert target query to version data"),
|
||||
Some(Targets::HashMap(mut map)) => {
|
||||
let q = map.remove("browsers").map(|q| match q {
|
||||
QueryOrVersion::Query(q) => q.exec().expect("failed to run query"),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
|
||||
let node = map.remove("node").map(|q| match q {
|
||||
QueryOrVersion::Version(v) => v,
|
||||
QueryOrVersion::Query(..) => unreachable!(),
|
||||
});
|
||||
|
||||
if map.is_empty() {
|
||||
if let Some(mut q) = q {
|
||||
q.node = node;
|
||||
return Ok(q);
|
||||
}
|
||||
}
|
||||
|
||||
unimplemented!("Targets: {:?}", map)
|
||||
}
|
||||
_ => unimplemented!("Option<Targets>: {:?}", v),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Query;
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let res = Query::Single("".into()).exec().unwrap();
|
||||
assert!(
|
||||
!res.is_any_target(),
|
||||
"empty query should return non-empty result"
|
||||
);
|
||||
}
|
||||
}
|
@ -1,9 +1,15 @@
|
||||
//! Module for browser versions
|
||||
|
||||
use std::{cmp, cmp::Ordering, fmt, str::FromStr};
|
||||
|
||||
use serde::{de, de::Visitor, Deserialize, Deserializer};
|
||||
|
||||
use crate::Versions;
|
||||
|
||||
/// A version of a browser.
|
||||
///
|
||||
/// This is similar to semver, but this assumes a production build. (No tag like
|
||||
/// `alpha`)
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Version {
|
||||
pub major: u16,
|
@ -12,10 +12,10 @@ version = "0.93.2"
|
||||
[dependencies]
|
||||
ahash = "0.7.4"
|
||||
anyhow = "1"
|
||||
browserslist-rs = "=0.8.0"
|
||||
dashmap = "4.0.2"
|
||||
indexmap = "1.6.2"
|
||||
once_cell = "1.9.0"
|
||||
preset_env_base = {version = "0.1.0", path = "../preset_env_base"}
|
||||
semver = {version = "1.0.4", features = ["serde"]}
|
||||
serde = {version = "1", features = ["derive"]}
|
||||
serde_json = "1"
|
||||
|
@ -1,11 +1,11 @@
|
||||
use indexmap::IndexSet;
|
||||
use preset_env_base::{version::should_enable, Versions};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{util::move_map::MoveMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
|
||||
use super::builtin::BUILTINS;
|
||||
use crate::{version::should_enable, Versions};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Entry {
|
||||
@ -17,7 +17,7 @@ pub struct Entry {
|
||||
impl Entry {
|
||||
pub fn new(target: Versions, regenerator: bool) -> Self {
|
||||
let is_any_target = target.is_any_target();
|
||||
let is_web_target = target.iter().any(|(k, v)| {
|
||||
let is_web_target = target.into_iter().any(|(k, v)| {
|
||||
if k == "node" {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use indexmap::IndexSet;
|
||||
use preset_env_base::{version::should_enable, Versions};
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
@ -9,7 +10,7 @@ use self::{
|
||||
builtin::BUILTINS,
|
||||
data::{BUILTIN_TYPES, INSTANCE_PROPERTIES, STATIC_PROPERTIES},
|
||||
};
|
||||
use crate::{util::DataMapExt, version::should_enable, Versions};
|
||||
use crate::util::DataMapExt;
|
||||
|
||||
mod builtin;
|
||||
mod data;
|
||||
|
@ -1,12 +1,15 @@
|
||||
use indexmap::IndexSet;
|
||||
use once_cell::sync::Lazy;
|
||||
use preset_env_base::{
|
||||
version::{should_enable, Version},
|
||||
Versions,
|
||||
};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{collections::AHashMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
|
||||
use super::compat::DATA as CORE_JS_COMPAT_DATA;
|
||||
use crate::{version::should_enable, Version, Versions};
|
||||
|
||||
static ENTRIES: Lazy<AHashMap<String, Vec<&'static str>>> = Lazy::new(|| {
|
||||
serde_json::from_str::<AHashMap<String, Vec<String>>>(include_str!("entries.json"))
|
||||
|
@ -1,4 +1,5 @@
|
||||
use indexmap::IndexSet;
|
||||
use preset_env_base::version::should_enable;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
@ -14,7 +15,6 @@ use crate::{
|
||||
},
|
||||
},
|
||||
util::DataMapExt,
|
||||
version::should_enable,
|
||||
Versions,
|
||||
};
|
||||
|
||||
|
@ -4,18 +4,11 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::{Context, Error};
|
||||
use dashmap::DashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use preset_env_base::query::{targets_to_versions, Query};
|
||||
pub use preset_env_base::{query::Targets, version::Version, BrowserData, Versions};
|
||||
use serde::Deserialize;
|
||||
use st_map::StaticMap;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{
|
||||
chain,
|
||||
collections::{AHashMap, AHashSet},
|
||||
comments::Comments,
|
||||
FromVariant, Mark, DUMMY_SP,
|
||||
};
|
||||
use swc_common::{chain, collections::AHashSet, comments::Comments, FromVariant, Mark, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms::{
|
||||
compat::{bugfixes, es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022, es3},
|
||||
@ -24,7 +17,7 @@ use swc_ecma_transforms::{
|
||||
use swc_ecma_utils::prepend_stmts;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
|
||||
pub use self::{transform_data::Feature, version::Version};
|
||||
pub use self::transform_data::Feature;
|
||||
|
||||
#[macro_use]
|
||||
mod util;
|
||||
@ -32,7 +25,6 @@ mod corejs2;
|
||||
mod corejs3;
|
||||
mod regenerator;
|
||||
mod transform_data;
|
||||
mod version;
|
||||
|
||||
pub fn preset_env<C>(global_mark: Mark, comments: Option<C>, c: Config) -> impl Fold
|
||||
where
|
||||
@ -265,46 +257,6 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
/// A map without allocation.
|
||||
#[derive(Debug, Default, Deserialize, Clone, Copy, StaticMap)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BrowserData<T: Default> {
|
||||
#[serde(default)]
|
||||
pub chrome: T,
|
||||
#[serde(default)]
|
||||
pub and_chr: T,
|
||||
#[serde(default)]
|
||||
pub and_ff: T,
|
||||
#[serde(default)]
|
||||
pub op_mob: T,
|
||||
#[serde(default)]
|
||||
pub ie: T,
|
||||
#[serde(default)]
|
||||
pub edge: T,
|
||||
#[serde(default)]
|
||||
pub firefox: T,
|
||||
#[serde(default)]
|
||||
pub safari: T,
|
||||
#[serde(default)]
|
||||
pub node: T,
|
||||
#[serde(default)]
|
||||
pub ios: T,
|
||||
#[serde(default)]
|
||||
pub samsung: T,
|
||||
#[serde(default)]
|
||||
pub opera: T,
|
||||
#[serde(default)]
|
||||
pub android: T,
|
||||
#[serde(default)]
|
||||
pub electron: T,
|
||||
#[serde(default)]
|
||||
pub phantom: T,
|
||||
#[serde(default)]
|
||||
pub opera_mobile: T,
|
||||
#[serde(default)]
|
||||
pub rhino: T,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Polyfills {
|
||||
mode: Option<Mode>,
|
||||
@ -451,57 +403,6 @@ pub enum Mode {
|
||||
Entry,
|
||||
}
|
||||
|
||||
pub type Versions = BrowserData<Option<Version>>;
|
||||
|
||||
impl BrowserData<Option<Version>> {
|
||||
pub(crate) fn is_any_target(&self) -> bool {
|
||||
self.iter().all(|(_, v)| v.is_none())
|
||||
}
|
||||
|
||||
pub(crate) fn parse_versions(distribs: Vec<browserslist::Distrib>) -> Result<Self, Error> {
|
||||
fn remap(key: &str) -> &str {
|
||||
match key {
|
||||
"and_chr" => "chrome",
|
||||
"and_ff" => "firefox",
|
||||
"ie_mob" => "ie",
|
||||
"ios_saf" => "ios",
|
||||
"op_mob" => "opera",
|
||||
_ => key,
|
||||
}
|
||||
}
|
||||
|
||||
let mut data: Versions = BrowserData::default();
|
||||
for dist in distribs {
|
||||
let browser = dist.name();
|
||||
let browser = remap(browser);
|
||||
let version = dist.version();
|
||||
match &*browser {
|
||||
"and_qq" | "and_uc" | "baidu" | "bb" | "kaios" | "op_mini" => continue,
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let version = version
|
||||
.split_once('-')
|
||||
.map(|(version, _)| version)
|
||||
.unwrap_or(version)
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
// lowest version
|
||||
if data[&browser].map(|v| v > version).unwrap_or(true) {
|
||||
for (k, v) in data.iter_mut() {
|
||||
if browser == k {
|
||||
*v = Some(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Config {
|
||||
@ -586,128 +487,3 @@ impl FeatureOrModule {
|
||||
(features, modules)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant)]
|
||||
#[serde(untagged)]
|
||||
pub enum Targets {
|
||||
Query(Query),
|
||||
EsModules(EsModules),
|
||||
Versions(Versions),
|
||||
HashMap(AHashMap<String, QueryOrVersion>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
||||
pub struct EsModules {
|
||||
esmodules: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant)]
|
||||
#[serde(untagged)]
|
||||
pub enum QueryOrVersion {
|
||||
Query(Query),
|
||||
Version(Version),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, FromVariant, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
#[serde(untagged)]
|
||||
pub enum Query {
|
||||
Single(String),
|
||||
Multiple(Vec<String>),
|
||||
}
|
||||
|
||||
type QueryResult = Result<Versions, Error>;
|
||||
|
||||
impl Query {
|
||||
fn exec(&self) -> QueryResult {
|
||||
fn query<T>(s: &[T]) -> QueryResult
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
let distribs = browserslist::resolve(
|
||||
s,
|
||||
browserslist::Opts::new()
|
||||
.mobile_to_desktop(true)
|
||||
.ignore_unknown_versions(true),
|
||||
)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to resolve browserslist query: {:?}",
|
||||
s.iter().map(|v| v.as_ref()).collect::<Vec<_>>()
|
||||
)
|
||||
})?;
|
||||
|
||||
let versions =
|
||||
BrowserData::parse_versions(distribs).expect("failed to parse browser version");
|
||||
|
||||
Ok(versions)
|
||||
}
|
||||
|
||||
static CACHE: Lazy<DashMap<Query, Versions, ahash::RandomState>> =
|
||||
Lazy::new(Default::default);
|
||||
|
||||
if let Some(v) = CACHE.get(self) {
|
||||
return Ok(*v);
|
||||
}
|
||||
|
||||
let result = match *self {
|
||||
Query::Single(ref s) => {
|
||||
if s.is_empty() {
|
||||
query(&["defaults"])
|
||||
} else {
|
||||
query(&[s])
|
||||
}
|
||||
}
|
||||
Query::Multiple(ref s) => query(s),
|
||||
}
|
||||
.context("failed to execute query")?;
|
||||
|
||||
CACHE.insert(self.clone(), result);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
fn targets_to_versions(v: Option<Targets>) -> Result<Versions, Error> {
|
||||
match v {
|
||||
None => Ok(Default::default()),
|
||||
Some(Targets::Versions(v)) => Ok(v),
|
||||
Some(Targets::Query(q)) => q
|
||||
.exec()
|
||||
.context("failed to convert target query to version data"),
|
||||
Some(Targets::HashMap(mut map)) => {
|
||||
let q = map.remove("browsers").map(|q| match q {
|
||||
QueryOrVersion::Query(q) => q.exec().expect("failed to run query"),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
|
||||
let node = map.remove("node").map(|q| match q {
|
||||
QueryOrVersion::Version(v) => v,
|
||||
QueryOrVersion::Query(..) => unreachable!(),
|
||||
});
|
||||
|
||||
if map.is_empty() {
|
||||
if let Some(mut q) = q {
|
||||
q.node = node;
|
||||
return Ok(q);
|
||||
}
|
||||
}
|
||||
|
||||
unimplemented!("Targets: {:?}", map)
|
||||
}
|
||||
_ => unimplemented!("Option<Targets>: {:?}", v),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Query;
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let res = Query::Single("".into()).exec().unwrap();
|
||||
assert!(
|
||||
!res.is_any_target(),
|
||||
"empty query should return non-empty result"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use preset_env_base::{
|
||||
version::{should_enable, Version},
|
||||
BrowserData, Versions,
|
||||
};
|
||||
use string_enum::StringEnum;
|
||||
use swc_common::collections::AHashMap;
|
||||
|
||||
use crate::{version::should_enable, BrowserData, Version, Versions};
|
||||
|
||||
impl Feature {
|
||||
pub fn should_enable(self, target: Versions, bugfixes: bool, default: bool) -> bool {
|
||||
let f = if bugfixes {
|
||||
|
@ -5,7 +5,7 @@
|
||||
"homepage": "https://swc.rs",
|
||||
"main": "./index.js",
|
||||
"author": "강동윤 <kdy1997.dev@gmail.com>",
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"swc",
|
||||
"swcpack",
|
||||
|
Loading…
Reference in New Issue
Block a user