mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor: make CompactStr immutable (#2620)
First step towards #2516. This replaces `compact_str::CompactString` with an immutable interface `CompactStr`. Currently just implemented as a wrapper around `CompactString` which hides all its mutation methods. A more optimized implementation to follow, which shrinks size of `CompactStr` to 16 bytes by removing the `capacity` field. The rationale for the change of name is: `CompactString` is like `String` in that it's mutable. `CompactStr` is more like `str` - immutable - so its name mirrors `str`.
This commit is contained in:
parent
0646bf34fa
commit
8001b2f796
5 changed files with 161 additions and 18 deletions
|
|
@ -36,7 +36,7 @@ impl std::ops::Deref for CatchErrorName {
|
|||
|
||||
impl Default for CatchErrorNameConfig {
|
||||
fn default() -> Self {
|
||||
Self { ignore: vec![], name: CompactStr::new_inline("error") }
|
||||
Self { ignore: vec![], name: CompactStr::new_const("error") }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -234,5 +234,5 @@ fn base54(n: usize) -> CompactStr {
|
|||
ret.push(BASE54_CHARS[num % base] as char);
|
||||
num /= base;
|
||||
}
|
||||
CompactStr::new(ret)
|
||||
CompactStr::new(&ret)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::{cell::RefCell, path::PathBuf, rc::Rc, sync::Arc};
|
|||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::{ast::*, AstKind, Trivias, TriviasMap, Visit};
|
||||
use oxc_diagnostics::Error;
|
||||
use oxc_span::{Atom, CompactStr, SourceType, Span};
|
||||
use oxc_span::{Atom, SourceType, Span};
|
||||
use oxc_syntax::{
|
||||
module_record::{ExportLocalName, ModuleRecord},
|
||||
operator::AssignmentOperator,
|
||||
|
|
@ -296,11 +296,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
pub fn declare_reference(&mut self, reference: Reference) -> ReferenceId {
|
||||
let reference_name = reference.name().clone();
|
||||
let reference_id = self.symbols.create_reference(reference);
|
||||
self.scope.add_unresolved_reference(
|
||||
self.current_scope_id,
|
||||
CompactStr::new(reference_name),
|
||||
reference_id,
|
||||
);
|
||||
self.scope.add_unresolved_reference(self.current_scope_id, reference_name, reference_id);
|
||||
reference_id
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,13 @@ export type Atom = string;
|
|||
export type CompactStr = string;
|
||||
"#;
|
||||
|
||||
/// Maximum length for inline string, which can be created with `CompactStr::new_const`.
|
||||
pub const MAX_INLINE_LEN: usize = 16;
|
||||
|
||||
/// An inlinable string for oxc_allocator.
|
||||
///
|
||||
/// Use [CompactStr] with [Atom::to_compact_str] or [Atom::into_compact_str] for the
|
||||
/// lifetimeless form.
|
||||
///
|
||||
/// [CompactStr]: crate::CompactStr
|
||||
#[derive(Clone, Eq)]
|
||||
pub enum Atom<'a> {
|
||||
Arena(&'a str),
|
||||
|
|
@ -59,18 +60,18 @@ impl<'a> Atom<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_compact_str(self) -> CompactString {
|
||||
pub fn into_compact_str(self) -> CompactStr {
|
||||
match self {
|
||||
Self::Arena(s) => CompactString::new(s),
|
||||
Self::Compact(s) => s,
|
||||
Self::Arena(s) => CompactStr::new(s),
|
||||
Self::Compact(s) => CompactStr::from(s),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_compact_str(&self) -> CompactString {
|
||||
pub fn to_compact_str(&self) -> CompactStr {
|
||||
match &self {
|
||||
Self::Arena(s) => CompactString::new(s),
|
||||
Self::Compact(s) => s.clone(),
|
||||
Self::Arena(s) => CompactStr::new(s),
|
||||
Self::Compact(s) => CompactStr::from(s.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,3 +146,150 @@ impl<'a> fmt::Display for Atom<'a> {
|
|||
fmt::Display::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Lifetimeless version of `Atom<'_>` which owns its own string data allocation.
|
||||
///
|
||||
/// `CompactStr` is immutable. Use `CompactStr::into_string` for a mutable `String`.
|
||||
///
|
||||
/// Currently implemented as just a wrapper around `compact_str::CompactString`,
|
||||
/// but will be reduced in size with a custom implementation later.
|
||||
#[derive(Clone, Eq)]
|
||||
pub struct CompactStr(CompactString);
|
||||
|
||||
impl CompactStr {
|
||||
/// Create a new `CompactStr`.
|
||||
///
|
||||
/// If `&str` is `'static` and no more than `MAX_INLINE_LEN` bytes,
|
||||
/// prefer `CompactStr::new_const` which creates the `CompactStr` at compile time.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// let s = CompactStr::new("long string which can't use new_const for");
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn new(s: &str) -> Self {
|
||||
Self(CompactString::new(s))
|
||||
}
|
||||
|
||||
/// Create a `CompactStr` at compile time.
|
||||
///
|
||||
/// String must be no longer than `MAX_INLINE_LEN` bytes.
|
||||
///
|
||||
/// Prefer this over `CompactStr::new` or `CompactStr::from` where string
|
||||
/// is `'static` and not longer than `MAX_INLINE_LEN` bytes.
|
||||
///
|
||||
/// # Panics
|
||||
/// Panics if string is longer than `MAX_INLINE_LEN` bytes.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// const S: CompactStr = CompactStr::new_const("short");
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn new_const(s: &'static str) -> Self {
|
||||
assert!(s.len() <= MAX_INLINE_LEN);
|
||||
Self(CompactString::new_inline(s))
|
||||
}
|
||||
|
||||
/// Get string content as a `&str` slice.
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
/// Convert a `CompactStr` into a `String`.
|
||||
#[inline]
|
||||
pub fn into_string(self) -> String {
|
||||
self.0.into_string()
|
||||
}
|
||||
|
||||
/// Get length of `CompactStr`.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
/// Check if a `CompactStr` is empty (0 length).
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CompactStr {
|
||||
fn from(s: &str) -> Self {
|
||||
Self(CompactString::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CompactStr {
|
||||
fn from(s: String) -> Self {
|
||||
Self(CompactString::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CompactString> for CompactStr {
|
||||
fn from(s: CompactString) -> Self {
|
||||
Self(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for CompactStr {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for CompactStr {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for CompactStr {
|
||||
fn borrow(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> PartialEq<T> for CompactStr {
|
||||
fn eq(&self, other: &T) -> bool {
|
||||
self.as_str() == other.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<CompactStr> for &str {
|
||||
fn eq(&self, other: &CompactStr) -> bool {
|
||||
*self == other.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl hash::Hash for CompactStr {
|
||||
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
|
||||
self.as_str().hash(hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CompactStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Debug::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CompactStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Display::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for CompactStr {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ mod source_type;
|
|||
mod span;
|
||||
|
||||
pub use crate::{
|
||||
atom::Atom,
|
||||
atom::{Atom, CompactStr, MAX_INLINE_LEN as ATOM_MAX_INLINE_LEN},
|
||||
source_type::{Language, LanguageVariant, ModuleKind, SourceType, VALID_EXTENSIONS},
|
||||
span::{GetSpan, Span, SPAN},
|
||||
};
|
||||
pub use compact_str::CompactString as CompactStr;
|
||||
|
|
|
|||
Loading…
Reference in a new issue