refactor(transformer)!: return String as error instead of OxcDiagnostic (#7424)

This commit is contained in:
Boshen 2024-11-22 16:22:49 +00:00
parent e88cf1bfd6
commit bb2c0c219b
9 changed files with 42 additions and 45 deletions

View file

@ -89,9 +89,11 @@ pub struct TransformOptions {
pub inject: Option<FxHashMap<String, Either<String, Vec<String>>>>,
}
impl From<TransformOptions> for oxc_transformer::TransformOptions {
fn from(options: TransformOptions) -> Self {
Self {
impl TryFrom<TransformOptions> for oxc_transformer::TransformOptions {
type Error = String;
fn try_from(options: TransformOptions) -> Result<Self, Self::Error> {
Ok(Self {
cwd: options.cwd.map(PathBuf::from).unwrap_or_default(),
typescript: options
.typescript
@ -99,7 +101,7 @@ impl From<TransformOptions> for oxc_transformer::TransformOptions {
.unwrap_or_default(),
jsx: options.jsx.map(Into::into).unwrap_or_default(),
..Self::default()
}
})
}
}

View file

@ -3,8 +3,6 @@ use std::str::FromStr;
use rustc_hash::FxHashMap;
use serde::Deserialize;
use oxc_diagnostics::Error;
pub use browserslist::Version;
use crate::options::{BrowserslistQuery, Engine, EngineTargets};
@ -35,7 +33,7 @@ pub enum BabelTargetsValue {
}
impl TryFrom<BabelTargets> for EngineTargets {
type Error = Error;
type Error = String;
fn try_from(value: BabelTargets) -> Result<Self, Self::Error> {
match value {
BabelTargets::String(s) => BrowserslistQuery::Single(s).exec(),
@ -52,7 +50,7 @@ impl TryFrom<BabelTargets> for EngineTargets {
continue;
};
let BabelTargetsValue::String(v) = value else {
return Err(Error::msg(format!("{value:?} is not a string for {key}.")));
return Err(format!("{value:?} is not a string for {key}."));
};
// TODO: Implement this target.
if key == "node" && v == "current" {
@ -66,16 +64,14 @@ impl TryFrom<BabelTargets> for EngineTargets {
// <https://babel.dev/docs/options#targets>:
// Supported environments: android, chrome, deno, edge, electron, firefox, ie, ios, node, opera, rhino, safari, samsung.
let Ok(engine) = Engine::from_str(&key) else {
return Err(Error::msg(format!("engine '{key}' is not supported.")));
return Err(format!("engine '{key}' is not supported."));
};
match Version::parse(&v) {
Ok(version) => {
engine_targets.insert(engine, version);
}
Err(err) => {
return Err(oxc_diagnostics::Error::msg(format!(
"Failed to parse `{v}` for `{key}`\n{err:?}"
)))
return Err(format!("Failed to parse `{v}` for `{key}`\n{err:?}"))
}
}
}

View file

@ -3,8 +3,6 @@ use std::sync::OnceLock;
use dashmap::DashMap;
use serde::Deserialize;
use oxc_diagnostics::{Error, OxcDiagnostic};
use super::EngineTargets;
#[derive(Debug, Clone, Deserialize, Eq, PartialEq, PartialOrd, Ord, Hash)]
@ -20,7 +18,7 @@ fn cache() -> &'static DashMap<BrowserslistQuery, EngineTargets> {
}
impl BrowserslistQuery {
pub fn exec(&self) -> Result<EngineTargets, Error> {
pub fn exec(&self) -> Result<EngineTargets, String> {
if let Some(v) = cache().get(self) {
return Ok(v.clone());
}
@ -50,9 +48,7 @@ impl BrowserslistQuery {
.collect::<Vec<_>>();
EngineTargets::parse_versions(versions)
}
Err(err) => {
return Err(OxcDiagnostic::error(format!("failed to resolve query: {err}")).into())
}
Err(err) => return Err(format!("failed to resolve query: {err}")),
};
cache().insert(self.clone(), result.clone());

View file

@ -2,7 +2,6 @@ use std::{str::FromStr, sync::OnceLock};
use browserslist::Version;
use cow_utils::CowUtils;
use oxc_diagnostics::Error;
use rustc_hash::FxHashMap;
use serde::Deserialize;
@ -38,17 +37,17 @@ impl Engine {
///
/// * No matching target
/// * Invalid version
pub fn parse_name_and_version(s: &str) -> Result<(Engine, Version), Error> {
pub fn parse_name_and_version(s: &str) -> Result<(Engine, Version), String> {
let s = s.cow_to_ascii_lowercase();
for (name, engine) in engines() {
if let Some(v) = s.strip_prefix(name) {
return Version::from_str(v).map(|version| (*engine,version))
.map_err(|_| Error::msg(
r#"All version numbers must be in the format "X", "X.Y", or "X.Y.Z" where X, Y, and Z are non-negative integers."#,
));
.map_err(|_|
String::from(r#"All version numbers must be in the format "X", "X.Y", or "X.Y.Z" where X, Y, and Z are non-negative integers."#),
);
}
}
Err(Error::msg(format!("Invalid target '{s}'.")))
Err(format!("Invalid target '{s}'."))
}
}

View file

@ -8,8 +8,6 @@ use browserslist::Version;
use rustc_hash::FxHashMap;
use serde::Deserialize;
use oxc_diagnostics::Error;
use super::{
babel::BabelTargets,
engine::Engine,
@ -42,7 +40,7 @@ impl EngineTargets {
/// # Errors
///
/// * Query is invalid.
pub fn try_from_query(query: &str) -> Result<Self, Error> {
pub fn try_from_query(query: &str) -> Result<Self, String> {
BrowserslistQuery::Single(query.to_string()).exec()
}

View file

@ -1,6 +1,5 @@
use std::str::FromStr;
use oxc_diagnostics::Error;
use serde::Deserialize;
use crate::{
@ -101,11 +100,14 @@ impl EnvOptions {
/// * When the query failed to parse.
///
/// [browserslist]: <https://github.com/browserslist/browserslist>
pub fn from_browserslist_query(query: &str) -> Result<Self, Error> {
pub fn from_browserslist_query(query: &str) -> Result<Self, String> {
EngineTargets::try_from_query(query).map(Self::from)
}
pub(crate) fn from_target(s: &str) -> Result<Self, Error> {
/// # Errors
///
/// * When the query failed to parse.
pub fn from_target(s: &str) -> Result<Self, String> {
if s.contains(',') {
Self::from_target_list(&s.split(',').collect::<Vec<_>>())
} else {
@ -113,7 +115,10 @@ impl EnvOptions {
}
}
pub(crate) fn from_target_list<S: AsRef<str>>(list: &[S]) -> Result<Self, Error> {
/// # Errors
///
/// * When the query failed to parse.
pub fn from_target_list<S: AsRef<str>>(list: &[S]) -> Result<Self, String> {
let mut es_target = None;
let mut engine_targets = EngineTargets::default();
@ -122,14 +127,14 @@ impl EnvOptions {
// Parse `esXXXX`.
if let Ok(target) = ESTarget::from_str(s) {
if let Some(target) = es_target {
return Err(Error::msg(format!("'{target}' is already specified.")));
return Err(format!("'{target}' is already specified."));
}
es_target = Some(target);
} else {
// Parse `chromeXX`, `edgeXX` etc.
let (engine, version) = Engine::parse_name_and_version(s)?;
if engine_targets.insert(engine, version).is_some() {
return Err(Error::msg(format!("'{s}' is already specified.")));
return Err(format!("'{s}' is already specified."));
}
}
}

View file

@ -10,8 +10,6 @@ mod module;
use std::path::PathBuf;
use oxc_diagnostics::Error;
use crate::{
common::helper_loader::{HelperLoaderMode, HelperLoaderOptions},
compiler_assumptions::CompilerAssumptions,
@ -97,7 +95,7 @@ impl TransformOptions {
/// * Same targets specified multiple times.
/// * No matching target.
/// * Invalid version.
pub fn from_target(s: &str) -> Result<Self, Error> {
pub fn from_target(s: &str) -> Result<Self, String> {
EnvOptions::from_target(s).map(|env| Self { env, ..Self::default() })
}
@ -115,7 +113,7 @@ impl TransformOptions {
/// * Same targets specified multiple times.
/// * No matching target.
/// * Invalid version.
pub fn from_target_list<S: AsRef<str>>(list: &[S]) -> Result<Self, Error> {
pub fn from_target_list<S: AsRef<str>>(list: &[S]) -> Result<Self, String> {
EnvOptions::from_target_list(list).map(|env| Self { env, ..Self::default() })
}
}
@ -129,13 +127,13 @@ impl From<ESTarget> for TransformOptions {
}
impl TryFrom<&BabelOptions> for TransformOptions {
type Error = Vec<Error>;
type Error = Vec<String>;
/// 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();
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 mut errors = Vec::<String>::new();
errors.extend(options.plugins.errors.iter().map(Clone::clone));
errors.extend(options.presets.errors.iter().map(Clone::clone));
let typescript = options
.presets

View file

@ -84,8 +84,11 @@ impl Compiler {
.transpose()?
.map(InjectGlobalVariablesConfig::new);
let transform_options =
options.map(oxc::transformer::TransformOptions::from).unwrap_or_default();
let transform_options = match options {
Some(options) => oxc::transformer::TransformOptions::try_from(options)
.map_err(|err| vec![OxcDiagnostic::error(err)])?,
None => oxc::transformer::TransformOptions::default(),
};
Ok(Self {
transform_options,

View file

@ -8,7 +8,7 @@ use oxc::parser::ParseOptions;
use oxc::{
allocator::Allocator,
codegen::{CodeGenerator, CodegenOptions},
diagnostics::{Error, NamedSource, OxcDiagnostic},
diagnostics::{NamedSource, OxcDiagnostic},
parser::Parser,
span::{SourceType, VALID_EXTENSIONS},
transformer::{BabelOptions, HelperLoaderMode, TransformOptions},
@ -27,7 +27,7 @@ pub struct TestCase {
pub path: PathBuf,
options: BabelOptions,
source_type: SourceType,
transform_options: Result<TransformOptions, Vec<Error>>,
transform_options: Result<TransformOptions, Vec<String>>,
pub errors: Vec<OxcDiagnostic>,
}