mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(transformer): deserialize BabelOptions::presets (#7047)
This commit is contained in:
parent
52c20d633c
commit
f83a760d8a
6 changed files with 249 additions and 243 deletions
|
|
@ -1,17 +1,16 @@
|
|||
mod env;
|
||||
mod plugins;
|
||||
mod presets;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
es2015::ArrowFunctionsOptions, es2018::ObjectRestSpreadOptions, es2022::ClassPropertiesOptions,
|
||||
jsx::JsxOptions, TypeScriptOptions,
|
||||
};
|
||||
|
||||
pub use env::{BabelEnvOptions, Targets};
|
||||
|
||||
use self::{plugins::BabelPlugins, presets::BabelPresets};
|
||||
|
||||
/// Babel options
|
||||
///
|
||||
/// <https://babel.dev/docs/options#plugin-and-preset-options>
|
||||
|
|
@ -28,7 +27,7 @@ pub struct BabelOptions {
|
|||
pub plugins: BabelPlugins,
|
||||
|
||||
#[serde(default)]
|
||||
pub presets: Vec<Value>, // Can be a string or an array
|
||||
pub presets: BabelPresets,
|
||||
|
||||
// Misc options
|
||||
pub source_type: Option<String>,
|
||||
|
|
@ -59,6 +58,38 @@ pub struct BabelOptions {
|
|||
pub external_helpers: bool,
|
||||
}
|
||||
|
||||
/// <https://babeljs.io/docs/options#pluginpreset-entries>
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct PluginPresetEntries(Vec<PluginPresetEntry>);
|
||||
|
||||
/// <https://babeljs.io/docs/options#pluginpreset-entries>
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum PluginPresetEntry {
|
||||
String(String),
|
||||
Vec1([String; 1]),
|
||||
Tuple(String, serde_json::Value),
|
||||
Triple(String, serde_json::Value, #[allow(unused)] String),
|
||||
}
|
||||
|
||||
impl PluginPresetEntry {
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::String(s) | Self::Tuple(s, _) | Self::Triple(s, _, _) => s,
|
||||
Self::Vec1(s) => &s[0],
|
||||
}
|
||||
}
|
||||
|
||||
fn value<T: DeserializeOwned + Default>(self) -> Result<T, String> {
|
||||
match self {
|
||||
Self::String(_) | Self::Vec1(_) => Ok(T::default()),
|
||||
Self::Tuple(name, v) | Self::Triple(name, v, _) => {
|
||||
serde_json::from_value::<T>(v).map_err(|err| format!("{name}: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum TestOs {
|
||||
|
|
@ -84,6 +115,7 @@ impl BabelOptions {
|
|||
pub fn from_test_path(path: &Path) -> Self {
|
||||
let mut babel_options: Option<Self> = None;
|
||||
let mut plugins_json = None;
|
||||
let mut presets_json = None;
|
||||
|
||||
for path in path.ancestors().take(3) {
|
||||
let file = path.join("options.json");
|
||||
|
|
@ -99,6 +131,11 @@ impl BabelOptions {
|
|||
plugins_json = new_plugins;
|
||||
}
|
||||
|
||||
let new_presets = new_value.as_object_mut().unwrap().remove("presets");
|
||||
if presets_json.is_none() {
|
||||
presets_json = new_presets;
|
||||
}
|
||||
|
||||
let new_options: Self = serde_json::from_value::<BabelOptions>(new_value)
|
||||
.unwrap_or_else(|err| panic!("{err:?}\n{file:?}\n{content}"));
|
||||
|
||||
|
|
@ -113,9 +150,6 @@ impl BabelOptions {
|
|||
existing_options.throws = Some(throws);
|
||||
}
|
||||
}
|
||||
if existing_options.presets.is_empty() {
|
||||
existing_options.presets = new_options.presets;
|
||||
}
|
||||
} else {
|
||||
babel_options = Some(new_options);
|
||||
}
|
||||
|
|
@ -123,7 +157,12 @@ impl BabelOptions {
|
|||
|
||||
let mut options = babel_options.unwrap_or_default();
|
||||
if let Some(plugins_json) = plugins_json {
|
||||
options.plugins = serde_json::from_value::<BabelPlugins>(plugins_json).unwrap();
|
||||
options.plugins = serde_json::from_value::<BabelPlugins>(plugins_json)
|
||||
.unwrap_or_else(|err| panic!("{err:?}\n{path:?}"));
|
||||
}
|
||||
if let Some(presets_json) = presets_json {
|
||||
options.presets = serde_json::from_value::<BabelPresets>(presets_json)
|
||||
.unwrap_or_else(|err| panic!("{err:?}\n{path:?}"));
|
||||
}
|
||||
options
|
||||
}
|
||||
|
|
@ -147,187 +186,4 @@ impl BabelOptions {
|
|||
pub fn is_unambiguous(&self) -> bool {
|
||||
self.source_type.as_ref().map_or(false, |s| s.as_str() == "unambiguous")
|
||||
}
|
||||
|
||||
pub fn get_preset(&self, name: &str) -> Option<Option<Value>> {
|
||||
self.presets.iter().find_map(|v| Self::get_value(v, name))
|
||||
}
|
||||
|
||||
pub fn has_preset(&self, name: &str) -> bool {
|
||||
self.get_preset(name).is_some()
|
||||
}
|
||||
|
||||
#[allow(clippy::option_option)]
|
||||
fn get_value(value: &Value, name: &str) -> Option<Option<Value>> {
|
||||
match value {
|
||||
Value::String(s) if s == name => Some(None),
|
||||
Value::Array(a) if a.first().and_then(Value::as_str).is_some_and(|s| s == name) => {
|
||||
Some(a.get(1).cloned())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||
pub struct SyntaxTypeScriptOptions {
|
||||
#[serde(default)]
|
||||
pub dts: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
pub struct SyntaxDecoratorOptions {
|
||||
#[serde(default)]
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(try_from = "PluginPresetEntries")]
|
||||
pub struct BabelPlugins {
|
||||
pub errors: Vec<String>,
|
||||
pub unsupported: Vec<String>,
|
||||
// syntax
|
||||
pub syntax_typescript: Option<SyntaxTypeScriptOptions>,
|
||||
pub syntax_jsx: bool,
|
||||
// decorators
|
||||
pub syntax_decorators: Option<SyntaxDecoratorOptions>,
|
||||
pub proposal_decorators: Option<SyntaxDecoratorOptions>,
|
||||
// ts
|
||||
pub typescript: Option<TypeScriptOptions>,
|
||||
// jsx
|
||||
pub react_jsx: Option<JsxOptions>,
|
||||
pub react_jsx_dev: Option<JsxOptions>,
|
||||
pub react_jsx_self: bool,
|
||||
pub react_jsx_source: bool,
|
||||
pub react_display_name: bool,
|
||||
// regexp
|
||||
pub sticky_flag: bool,
|
||||
pub unicode_flag: bool,
|
||||
pub dot_all_flag: bool,
|
||||
pub look_behind_assertions: bool,
|
||||
pub named_capture_groups: bool,
|
||||
pub unicode_property_escapes: bool,
|
||||
pub match_indices: bool,
|
||||
/// Enables plugin to transform the RegExp literal has `v` flag
|
||||
pub set_notation: bool,
|
||||
// ES2015
|
||||
pub arrow_function: Option<ArrowFunctionsOptions>,
|
||||
// ES2016
|
||||
pub exponentiation_operator: bool,
|
||||
// ES2017
|
||||
pub async_to_generator: bool,
|
||||
// ES2018
|
||||
pub object_rest_spread: Option<ObjectRestSpreadOptions>,
|
||||
pub async_generator_functions: bool,
|
||||
// ES2019
|
||||
pub optional_catch_binding: bool,
|
||||
// ES2020
|
||||
pub nullish_coalescing_operator: bool,
|
||||
// ES2021
|
||||
pub logical_assignment_operators: bool,
|
||||
// ES2022
|
||||
pub class_static_block: bool,
|
||||
pub class_properties: Option<ClassPropertiesOptions>,
|
||||
}
|
||||
|
||||
/// <https://babeljs.io/docs/options#pluginpreset-entries>
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct PluginPresetEntries(Vec<PluginPresetEntry>);
|
||||
|
||||
impl TryFrom<PluginPresetEntries> for BabelPlugins {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(entries: PluginPresetEntries) -> Result<Self, Self::Error> {
|
||||
let mut p = BabelPlugins::default();
|
||||
for entry in entries.0 {
|
||||
match entry.name() {
|
||||
"typescript" | "syntax-typescript" => {
|
||||
p.syntax_typescript = Some(entry.value::<SyntaxTypeScriptOptions>()?);
|
||||
}
|
||||
"jsx" | "syntax-jsx" => p.syntax_jsx = true,
|
||||
"syntax-decorators" => {
|
||||
p.syntax_decorators = Some(entry.value::<SyntaxDecoratorOptions>()?);
|
||||
}
|
||||
"proposal-decorators" => {
|
||||
p.proposal_decorators = Some(entry.value::<SyntaxDecoratorOptions>()?);
|
||||
}
|
||||
"transform-typescript" => {
|
||||
p.typescript =
|
||||
entry.value::<TypeScriptOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-jsx" => {
|
||||
p.react_jsx =
|
||||
entry.value::<JsxOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-jsx-development" => {
|
||||
p.react_jsx_dev =
|
||||
entry.value::<JsxOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-display-name" => p.react_display_name = true,
|
||||
"transform-react-jsx-self" => p.react_jsx_self = true,
|
||||
"transform-react-jsx-source" => p.react_jsx_source = true,
|
||||
"transform-sticky-regex" => p.sticky_flag = true,
|
||||
"transform-unicode-regex" => p.unicode_flag = true,
|
||||
"transform-dotall-regex" => p.dot_all_flag = true,
|
||||
"esbuild-regexp-lookbehind-assertions" => p.look_behind_assertions = true,
|
||||
"transform-named-capturing-groups-regex" => p.named_capture_groups = true,
|
||||
"transform-unicode-property-regex" => p.unicode_property_escapes = true,
|
||||
"esbuild-regexp-match-indices" => p.match_indices = true,
|
||||
"transform-unicode-sets-regex" => p.set_notation = true,
|
||||
"transform-arrow-functions" => {
|
||||
p.arrow_function = entry
|
||||
.value::<ArrowFunctionsOptions>()
|
||||
.map_err(|err| p.errors.push(err))
|
||||
.ok();
|
||||
}
|
||||
"transform-exponentiation-operator" => p.exponentiation_operator = true,
|
||||
"transform-async-to-generator" => p.async_to_generator = true,
|
||||
"transform-object-rest-spread" => {
|
||||
p.object_rest_spread = entry
|
||||
.value::<ObjectRestSpreadOptions>()
|
||||
.inspect_err(|err| p.errors.push(err.to_string()))
|
||||
.ok();
|
||||
}
|
||||
"transform-async-generator-functions" => p.async_generator_functions = true,
|
||||
"transform-optional-catch-binding" => p.optional_catch_binding = true,
|
||||
"transform-nullish-coalescing-operator" => p.nullish_coalescing_operator = true,
|
||||
"transform-logical-assignment-operators" => p.logical_assignment_operators = true,
|
||||
"transform-class-static-block" => p.class_static_block = true,
|
||||
"transform-class-properties" => {
|
||||
p.class_properties = entry
|
||||
.value::<ClassPropertiesOptions>()
|
||||
.inspect_err(|err| p.errors.push(err.to_string()))
|
||||
.ok();
|
||||
}
|
||||
s => p.unsupported.push(s.to_string()),
|
||||
}
|
||||
}
|
||||
Ok(p)
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://babeljs.io/docs/options#pluginpreset-entries>
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum PluginPresetEntry {
|
||||
String(String),
|
||||
Vec1([String; 1]),
|
||||
Tuple(String, serde_json::Value),
|
||||
}
|
||||
|
||||
impl PluginPresetEntry {
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::String(s) | Self::Tuple(s, _) => s,
|
||||
Self::Vec1(s) => &s[0],
|
||||
}
|
||||
}
|
||||
|
||||
fn value<T: DeserializeOwned + Default>(self) -> Result<T, String> {
|
||||
match self {
|
||||
Self::String(_) | Self::Vec1(_) => Ok(T::default()),
|
||||
Self::Tuple(name, v) => {
|
||||
serde_json::from_value::<T>(v).map_err(|err| format!("{name}: {err}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
141
crates/oxc_transformer/src/options/babel/plugins.rs
Normal file
141
crates/oxc_transformer/src/options/babel/plugins.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
es2015::ArrowFunctionsOptions, es2018::ObjectRestSpreadOptions, es2022::ClassPropertiesOptions,
|
||||
jsx::JsxOptions, TypeScriptOptions,
|
||||
};
|
||||
|
||||
use super::PluginPresetEntries;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||
pub struct SyntaxTypeScriptOptions {
|
||||
#[serde(default)]
|
||||
pub dts: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
pub struct SyntaxDecoratorOptions {
|
||||
#[serde(default)]
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(try_from = "PluginPresetEntries")]
|
||||
pub struct BabelPlugins {
|
||||
pub errors: Vec<String>,
|
||||
pub unsupported: Vec<String>,
|
||||
// syntax
|
||||
pub syntax_typescript: Option<SyntaxTypeScriptOptions>,
|
||||
pub syntax_jsx: bool,
|
||||
// decorators
|
||||
pub syntax_decorators: Option<SyntaxDecoratorOptions>,
|
||||
pub proposal_decorators: Option<SyntaxDecoratorOptions>,
|
||||
// ts
|
||||
pub typescript: Option<TypeScriptOptions>,
|
||||
// jsx
|
||||
pub react_jsx: Option<JsxOptions>,
|
||||
pub react_jsx_dev: Option<JsxOptions>,
|
||||
pub react_jsx_self: bool,
|
||||
pub react_jsx_source: bool,
|
||||
pub react_display_name: bool,
|
||||
// regexp
|
||||
pub sticky_flag: bool,
|
||||
pub unicode_flag: bool,
|
||||
pub dot_all_flag: bool,
|
||||
pub look_behind_assertions: bool,
|
||||
pub named_capture_groups: bool,
|
||||
pub unicode_property_escapes: bool,
|
||||
pub match_indices: bool,
|
||||
/// Enables plugin to transform the RegExp literal has `v` flag
|
||||
pub set_notation: bool,
|
||||
// ES2015
|
||||
pub arrow_function: Option<ArrowFunctionsOptions>,
|
||||
// ES2016
|
||||
pub exponentiation_operator: bool,
|
||||
// ES2017
|
||||
pub async_to_generator: bool,
|
||||
// ES2018
|
||||
pub object_rest_spread: Option<ObjectRestSpreadOptions>,
|
||||
pub async_generator_functions: bool,
|
||||
// ES2019
|
||||
pub optional_catch_binding: bool,
|
||||
// ES2020
|
||||
pub nullish_coalescing_operator: bool,
|
||||
// ES2021
|
||||
pub logical_assignment_operators: bool,
|
||||
// ES2022
|
||||
pub class_static_block: bool,
|
||||
pub class_properties: Option<ClassPropertiesOptions>,
|
||||
}
|
||||
|
||||
impl TryFrom<PluginPresetEntries> for BabelPlugins {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(entries: PluginPresetEntries) -> Result<Self, Self::Error> {
|
||||
let mut p = Self::default();
|
||||
for entry in entries.0 {
|
||||
match entry.name() {
|
||||
"typescript" | "syntax-typescript" => {
|
||||
p.syntax_typescript = Some(entry.value::<SyntaxTypeScriptOptions>()?);
|
||||
}
|
||||
"jsx" | "syntax-jsx" => p.syntax_jsx = true,
|
||||
"syntax-decorators" => {
|
||||
p.syntax_decorators = Some(entry.value::<SyntaxDecoratorOptions>()?);
|
||||
}
|
||||
"proposal-decorators" => {
|
||||
p.proposal_decorators = Some(entry.value::<SyntaxDecoratorOptions>()?);
|
||||
}
|
||||
"transform-typescript" => {
|
||||
p.typescript =
|
||||
entry.value::<TypeScriptOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-jsx" => {
|
||||
p.react_jsx =
|
||||
entry.value::<JsxOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-jsx-development" => {
|
||||
p.react_jsx_dev =
|
||||
entry.value::<JsxOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"transform-react-display-name" => p.react_display_name = true,
|
||||
"transform-react-jsx-self" => p.react_jsx_self = true,
|
||||
"transform-react-jsx-source" => p.react_jsx_source = true,
|
||||
"transform-sticky-regex" => p.sticky_flag = true,
|
||||
"transform-unicode-regex" => p.unicode_flag = true,
|
||||
"transform-dotall-regex" => p.dot_all_flag = true,
|
||||
"esbuild-regexp-lookbehind-assertions" => p.look_behind_assertions = true,
|
||||
"transform-named-capturing-groups-regex" => p.named_capture_groups = true,
|
||||
"transform-unicode-property-regex" => p.unicode_property_escapes = true,
|
||||
"esbuild-regexp-match-indices" => p.match_indices = true,
|
||||
"transform-unicode-sets-regex" => p.set_notation = true,
|
||||
"transform-arrow-functions" => {
|
||||
p.arrow_function = entry
|
||||
.value::<ArrowFunctionsOptions>()
|
||||
.map_err(|err| p.errors.push(err))
|
||||
.ok();
|
||||
}
|
||||
"transform-exponentiation-operator" => p.exponentiation_operator = true,
|
||||
"transform-async-to-generator" => p.async_to_generator = true,
|
||||
"transform-object-rest-spread" => {
|
||||
p.object_rest_spread = entry
|
||||
.value::<ObjectRestSpreadOptions>()
|
||||
.map_err(|err| p.errors.push(err))
|
||||
.ok();
|
||||
}
|
||||
"transform-async-generator-functions" => p.async_generator_functions = true,
|
||||
"transform-optional-catch-binding" => p.optional_catch_binding = true,
|
||||
"transform-nullish-coalescing-operator" => p.nullish_coalescing_operator = true,
|
||||
"transform-logical-assignment-operators" => p.logical_assignment_operators = true,
|
||||
"transform-class-static-block" => p.class_static_block = true,
|
||||
"transform-class-properties" => {
|
||||
p.class_properties = entry
|
||||
.value::<ClassPropertiesOptions>()
|
||||
.map_err(|err| p.errors.push(err))
|
||||
.ok();
|
||||
}
|
||||
s => p.unsupported.push(s.to_string()),
|
||||
}
|
||||
}
|
||||
Ok(p)
|
||||
}
|
||||
}
|
||||
42
crates/oxc_transformer/src/options/babel/presets.rs
Normal file
42
crates/oxc_transformer/src/options/babel/presets.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use super::{BabelEnvOptions, PluginPresetEntries};
|
||||
|
||||
use crate::{JsxOptions, TypeScriptOptions};
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(try_from = "PluginPresetEntries")]
|
||||
pub struct BabelPresets {
|
||||
pub errors: Vec<String>,
|
||||
pub unsupported: Vec<String>,
|
||||
|
||||
pub env: Option<BabelEnvOptions>,
|
||||
|
||||
pub jsx: Option<JsxOptions>,
|
||||
|
||||
pub typescript: Option<TypeScriptOptions>,
|
||||
}
|
||||
|
||||
impl TryFrom<PluginPresetEntries> for BabelPresets {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(entries: PluginPresetEntries) -> Result<Self, Self::Error> {
|
||||
let mut p = Self::default();
|
||||
for entry in entries.0 {
|
||||
match entry.name() {
|
||||
"env" => {
|
||||
p.env = entry.value::<BabelEnvOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"typescript" => {
|
||||
p.typescript =
|
||||
entry.value::<TypeScriptOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
"react" => {
|
||||
p.jsx = entry.value::<JsxOptions>().map_err(|err| p.errors.push(err)).ok();
|
||||
}
|
||||
s => p.unsupported.push(s.to_string()),
|
||||
}
|
||||
}
|
||||
Ok(p)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use oxc_diagnostics::{Error, OxcDiagnostic};
|
||||
use oxc_diagnostics::Error;
|
||||
|
||||
use crate::{
|
||||
es2015::ES2015Options, es2016::ES2016Options, es2017::ES2017Options, es2018::ES2018Options,
|
||||
|
|
@ -126,17 +126,11 @@ impl TryFrom<&BabelOptions> for EnvOptions {
|
|||
|
||||
/// If the `options` contains any unknown fields, they will be returned as a list of errors.
|
||||
fn try_from(options: &BabelOptions) -> Result<Self, Self::Error> {
|
||||
let mut errors = Vec::<Error>::new();
|
||||
|
||||
let env = options
|
||||
.get_preset("env")
|
||||
.flatten()
|
||||
.and_then(|value| {
|
||||
serde_json::from_value::<BabelEnvOptions>(value)
|
||||
.inspect_err(|err| report_error("env", err, true, &mut errors))
|
||||
.ok()
|
||||
})
|
||||
.and_then(|env_options| EnvOptions::try_from(&env_options).ok())
|
||||
.presets
|
||||
.env
|
||||
.as_ref()
|
||||
.and_then(|env_options| EnvOptions::try_from(env_options).ok())
|
||||
.unwrap_or_default();
|
||||
|
||||
let regexp = RegExpOptions {
|
||||
|
|
@ -195,16 +189,6 @@ impl TryFrom<&BabelOptions> for EnvOptions {
|
|||
class_properties: options.plugins.class_properties.or(env.es2022.class_properties),
|
||||
};
|
||||
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
Ok(Self { regexp, es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022 })
|
||||
}
|
||||
}
|
||||
|
||||
fn report_error(name: &str, err: &serde_json::Error, is_preset: bool, errors: &mut Vec<Error>) {
|
||||
let message =
|
||||
if is_preset { format!("preset-{name}: {err}",) } else { format!("{name}: {err}",) };
|
||||
errors.push(OxcDiagnostic::error(message).into());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ mod env;
|
|||
use std::path::PathBuf;
|
||||
|
||||
use env::EnvOptions;
|
||||
use oxc_diagnostics::{Error, OxcDiagnostic};
|
||||
use oxc_diagnostics::Error;
|
||||
|
||||
use crate::{
|
||||
common::helper_loader::{HelperLoaderMode, HelperLoaderOptions},
|
||||
|
|
@ -73,34 +73,25 @@ impl TryFrom<&BabelOptions> for TransformOptions {
|
|||
fn try_from(options: &BabelOptions) -> Result<Self, Self::Error> {
|
||||
let mut errors = Vec::<Error>::new();
|
||||
errors.extend(options.plugins.errors.iter().map(|err| Error::msg(err.clone())));
|
||||
errors.extend(options.presets.errors.iter().map(|err| Error::msg(err.clone())));
|
||||
|
||||
let assumptions = if options.assumptions.is_null() {
|
||||
CompilerAssumptions::default()
|
||||
} else {
|
||||
serde_json::from_value::<CompilerAssumptions>(options.assumptions.clone())
|
||||
.inspect_err(|err| errors.push(OxcDiagnostic::error(err.to_string()).into()))
|
||||
.map_err(|err| errors.push(Error::msg(err)))
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
let typescript = if options.has_preset("typescript") {
|
||||
options.get_preset("typescript").and_then(|options| {
|
||||
options
|
||||
.map(|options| {
|
||||
serde_json::from_value::<TypeScriptOptions>(options)
|
||||
.inspect_err(|err| report_error("typescript", err, true, &mut errors))
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
})
|
||||
} else {
|
||||
options.plugins.typescript.clone()
|
||||
}
|
||||
.unwrap_or_default();
|
||||
let typescript = options
|
||||
.presets
|
||||
.typescript
|
||||
.clone()
|
||||
.or_else(|| options.plugins.typescript.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
let jsx = if let Some(value) = options.get_preset("react").flatten() {
|
||||
serde_json::from_value::<JsxOptions>(value)
|
||||
.inspect_err(|err| report_error("react", err, true, &mut errors))
|
||||
.unwrap_or_default()
|
||||
let jsx = if let Some(options) = &options.presets.jsx {
|
||||
options.clone()
|
||||
} else {
|
||||
let mut jsx_options = if let Some(options) = &options.plugins.react_jsx_dev {
|
||||
options.clone()
|
||||
|
|
@ -148,9 +139,3 @@ impl TryFrom<&BabelOptions> for TransformOptions {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn report_error(name: &str, err: &serde_json::Error, is_preset: bool, errors: &mut Vec<Error>) {
|
||||
let message =
|
||||
if is_preset { format!("preset-{name}: {err}",) } else { format!("{name}: {err}",) };
|
||||
errors.push(OxcDiagnostic::error(message).into());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,9 +145,7 @@ pub trait TestCase {
|
|||
}
|
||||
|
||||
// Skip custom preset and flow
|
||||
if options.presets.iter().any(|value| value.as_str().is_some_and(|s| s.starts_with("./")))
|
||||
|| options.get_preset("flow").is_some()
|
||||
{
|
||||
if options.presets.unsupported.iter().any(|s| s.starts_with("./") || s == "flow") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue