Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 40 additions & 38 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ multiple_crate_versions = "allow"

[workspace.dependencies]
# External oxc crates from crates.io
oxc_allocator = "0.154"
oxc_ast = "0.154"
oxc_ast_visit = "0.154"
oxc_diagnostics = "0.154"
oxc_napi = "0.154"
oxc_parser = "0.154"
oxc_semantic = "0.154"
oxc_span = "0.154"
oxc_syntax = "0.154"
oxc_allocator = "0.155"
oxc_ast = "0.155"
oxc_ast_visit = "0.155"
oxc_diagnostics = "0.155"
oxc_napi = "0.155"
oxc_parser = "0.155"
oxc_semantic = "0.155"
oxc_span = "0.155"
oxc_syntax = "0.155"
oxc_sourcemap = "9.0.0"
oxc_str = "0.154"
oxc_transformer = "0.154"
oxc_codegen = "0.154"
oxc_str = "0.155"
oxc_transformer = "0.155"
oxc_codegen = "0.155"

# Internal
oxc_angular_compiler = { path = "crates/oxc_angular_compiler" }
Expand Down
15 changes: 8 additions & 7 deletions crates/angular_conformance/src/extractor/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! and options parsing from AST expressions.

use oxc_ast::ast::{Argument, CallExpression, Expression};
use oxc_str::JSStr;

use crate::test_case::{HtmlLexerOptions, HtmlParserOptions, LexerRange, ParseOptions};

Expand All @@ -13,11 +14,11 @@ impl SpecExtractor {
/// Extract a string from a string literal expression
pub(super) fn extract_string(&self, expr: &Expression<'_>) -> Option<String> {
match expr {
Expression::StringLiteral(lit) => Some(lit.value.to_string()),
Expression::StringLiteral(lit) => lit.value.as_str().map(str::to_string),
Expression::TemplateLiteral(lit) if lit.expressions.is_empty() => {
// Template literal with no expressions - use cooked value (with escapes processed)
if lit.quasis.len() == 1 {
lit.quasis[0].value.cooked.as_ref().map(std::string::ToString::to_string)
lit.quasis[0].value.cooked.and_then(JSStr::as_str).map(str::to_string)
} else {
None
}
Expand All @@ -44,17 +45,17 @@ impl SpecExtractor {
/// Resolve a string value directly from an expression
pub(super) fn resolve_string_from_expression(&self, expr: &Expression<'_>) -> Option<String> {
match expr {
Expression::StringLiteral(lit) => Some(lit.value.to_string()),
Expression::StringLiteral(lit) => lit.value.as_str().map(str::to_string),
Expression::TemplateLiteral(lit) if lit.expressions.is_empty() => {
// Template literal with no expressions - use cooked value
if lit.quasis.len() == 1 {
lit.quasis[0].value.cooked.as_ref().map(std::string::ToString::to_string)
lit.quasis[0].value.cooked.and_then(JSStr::as_str).map(str::to_string)
} else {
// Multiple quasis but no expressions means we can concatenate them
let parts: Vec<&str> = lit
.quasis
.iter()
.filter_map(|q| q.value.cooked.as_ref().map(oxc_str::Str::as_str))
.filter_map(|q| q.value.cooked.and_then(JSStr::as_str))
.collect();
Some(parts.join(""))
}
Expand Down Expand Up @@ -135,7 +136,7 @@ impl SpecExtractor {
pub(super) fn extract_json_value(&self, expr: &Expression<'_>) -> Option<serde_json::Value> {
match expr {
Expression::StringLiteral(lit) => {
Some(serde_json::Value::String(lit.value.to_string()))
lit.value.as_str().map(|s| serde_json::Value::String(s.to_string()))
}
Expression::NumericLiteral(lit) => {
serde_json::Number::from_f64(lit.value.into()).map(serde_json::Value::Number)
Expand Down Expand Up @@ -183,7 +184,7 @@ impl SpecExtractor {
lit.quasis[0]
.value
.cooked
.as_ref()
.and_then(JSStr::as_str)
.map(|s| serde_json::Value::String(s.to_string()))
} else {
None
Expand Down
13 changes: 9 additions & 4 deletions crates/oxc_angular_compiler/src/class_metadata/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1386,10 +1386,13 @@ fn get_decorator_name<'a>(decorator: &Decorator<'a>) -> Option<&'a str> {
}

/// Get property key name as an Atom.
///
/// A string key holding a lone surrogate has no `&str` form, so it returns
/// `None` (and [`convert_plain_properties`] skips such entries too).
fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option<Ident<'a>> {
match key {
PropertyKey::StaticIdentifier(id) => Some(id.name.into()),
PropertyKey::StringLiteral(lit) => Some(lit.value.into()),
PropertyKey::StringLiteral(lit) => lit.value.as_str().map(Ident::from),
_ => None,
}
}
Expand All @@ -1400,13 +1403,15 @@ fn get_property_key_name<'a>(key: &PropertyKey<'a>) -> Option<Ident<'a>> {
/// string-literal key (`'x-y'`, `'x'`) is always quoted in the emitted object
/// literal; a bare identifier is not. A no-substitution template literal
/// counts too; private (`#x`), computed and numeric keys have no usable name
/// and return `None`.
/// and return `None`, as does a string key holding a lone surrogate (it has
/// no `&str` form, so the member is left out).
fn member_key_name<'a>(key: &PropertyKey<'a>) -> Option<(Ident<'a>, bool)> {
let quoted = |value: oxc_str::JSStr<'a>| value.as_str().map(|name| (Ident::from(name), true));
match key {
PropertyKey::StaticIdentifier(id) => Some((id.name.into(), false)),
PropertyKey::StringLiteral(lit) => Some((lit.value.into(), true)),
PropertyKey::StringLiteral(lit) => quoted(lit.value),
PropertyKey::TemplateLiteral(tpl) if tpl.expressions.is_empty() => {
tpl.quasis.first().and_then(|q| q.value.cooked.clone().map(|v| (v.into(), true)))
tpl.quasis.first().and_then(|q| q.value.cooked.and_then(quoted))
}
_ => None,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,14 +871,17 @@ impl Inner {
return;
}

// A source with a lone surrogate (`'\uD800'`) can't be
// resolved: keep the specifier's own info, unchased.
let source = decl.source.value.as_str();
for spec in &decl.specifiers {
let exported_name = spec.exported.name().to_string();
let local_name = spec.local.name().to_string();
exports.insert(
exported_name,
ExportInfo {
is_type_only: spec.export_kind.is_type(),
re_export_source: Some((decl.source.value.to_string(), local_name)),
re_export_source: source.map(|source| (source.to_string(), local_name)),
value_local: None,
},
);
Expand All @@ -901,7 +904,9 @@ impl Inner {
);
}
Statement::ExportAllDeclaration(decl) => {
let source_module = decl.source.value.to_string();
// A source with a lone surrogate (`'\uD800'`) can't be resolved.
let Some(source_module) = decl.source.value.as_str() else { return };
let source_module = source_module.to_string();
if let Some(exported) = &decl.exported {
// export * as X from './other'
exports.insert(
Expand Down
Loading
Loading