From e5a38f8196b5829d1e9aa1d0c482d8c2fba4c028 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Thu, 19 Sep 2024 09:45:27 +0200 Subject: [PATCH] String -> EcoString --- compiler-core/src/javascript.rs | 14 +++++++------- compiler-core/src/javascript/import.rs | 22 +++++++++++----------- compiler-core/src/javascript/typescript.rs | 10 +++++----- compiler-core/src/parse.rs | 2 +- compiler-core/src/parse/lexer.rs | 4 +++- compiler-core/src/parse/token.rs | 2 +- compiler-core/src/pretty.rs | 21 ++++++--------------- 7 files changed, 34 insertions(+), 41 deletions(-) diff --git a/compiler-core/src/javascript.rs b/compiler-core/src/javascript.rs index f99f6a290e5..82becb1ecf3 100644 --- a/compiler-core/src/javascript.rs +++ b/compiler-core/src/javascript.rs @@ -373,22 +373,22 @@ impl<'a> Generator<'a> { imports } - fn import_path(&self, package: &'a str, module: &'a str) -> String { + fn import_path(&self, package: &'a str, module: &'a str) -> EcoString { // TODO: strip shared prefixed between current module and imported // module to avoid descending and climbing back out again if package == self.module.type_info.package || package.is_empty() { // Same package match self.current_module_name_segments_count { - 1 => format!("./{module}.mjs"), + 1 => eco_format!("./{module}.mjs"), _ => { let prefix = "../".repeat(self.current_module_name_segments_count - 1); - format!("{prefix}{module}.mjs") + eco_format!("{prefix}{module}.mjs") } } } else { // Different package let prefix = "../".repeat(self.current_module_name_segments_count); - format!("{prefix}{package}/{module}.mjs") + eco_format!("{prefix}{package}/{module}.mjs") } } @@ -413,7 +413,7 @@ impl<'a> Generator<'a> { Some((AssignName::Variable(name), _)) => (false, name.as_str()), }; - let module_name = format!("${module_name}"); + let module_name = eco_format!("${module_name}"); let path = self.import_path(package, module); let unqualified_imports = unqualified.iter().map(|i| { let alias = i.as_name.as_ref().map(|n| { @@ -448,9 +448,9 @@ impl<'a> Generator<'a> { }, }; if publicity.is_importable() { - imports.register_export(maybe_escape_identifier_string(name).to_string()) + imports.register_export(maybe_escape_identifier_string(name)) } - imports.register_module(module.to_string(), [], [member]); + imports.register_module(EcoString::from(module), [], [member]); } fn module_constant( diff --git a/compiler-core/src/javascript/import.rs b/compiler-core/src/javascript/import.rs index d6454ee306a..f982d496fdd 100644 --- a/compiler-core/src/javascript/import.rs +++ b/compiler-core/src/javascript/import.rs @@ -14,8 +14,8 @@ use crate::{ /// #[derive(Debug, Default)] pub(crate) struct Imports<'a> { - imports: HashMap>, - exports: HashSet, + imports: HashMap>, + exports: HashSet, } impl<'a> Imports<'a> { @@ -23,14 +23,14 @@ impl<'a> Imports<'a> { Self::default() } - pub fn register_export(&mut self, export: String) { + pub fn register_export(&mut self, export: EcoString) { let _ = self.exports.insert(export); } pub fn register_module( &mut self, - path: String, - aliases: impl IntoIterator, + path: EcoString, + aliases: impl IntoIterator, unqualified_imports: impl IntoIterator>, ) { let import = self @@ -56,7 +56,7 @@ impl<'a> Imports<'a> { self.exports .into_iter() .sorted() - .map(|string| EcoString::from(string).to_doc()), + .map(|string| string.to_doc()), break_(",", ", "), ); let names = docvec![ @@ -80,13 +80,13 @@ impl<'a> Imports<'a> { #[derive(Debug)] struct Import<'a> { - path: String, - aliases: HashSet, + path: EcoString, + aliases: HashSet, unqualified: Vec>, } impl<'a> Import<'a> { - fn new(path: String) -> Self { + fn new(path: EcoString) -> Self { Self { path, aliases: Default::default(), @@ -95,7 +95,7 @@ impl<'a> Import<'a> { } pub fn into_doc(self, codegen_target: JavaScriptCodegenTarget) -> Document<'a> { - let path = EcoString::from(self.path).to_doc(); + let path = self.path.to_doc(); let import_modifier = if codegen_target == JavaScriptCodegenTarget::TypeScriptDeclarations { "type " } else { @@ -106,7 +106,7 @@ impl<'a> Import<'a> { "import ", import_modifier, "* as ", - EcoString::from(alias), + alias, " from \"", path.clone(), r#"";"#, diff --git a/compiler-core/src/javascript/typescript.rs b/compiler-core/src/javascript/typescript.rs index 11b5e2f3d6a..22e605caba3 100644 --- a/compiler-core/src/javascript/typescript.rs +++ b/compiler-core/src/javascript/typescript.rs @@ -265,28 +265,28 @@ impl<'a> TypeScriptGenerator<'a> { /// fn register_import(&mut self, imports: &mut Imports<'a>, package: &'a str, module: &'a str) { let path = self.import_path(package, module); - imports.register_module(path, [self.module_name(module).to_string()], []); + imports.register_module(path, [self.module_name(module)], []); } /// Calculates the path of where to import an external module from /// - fn import_path(&self, package: &'a str, module: &'a str) -> String { + fn import_path(&self, package: &'a str, module: &'a str) -> EcoString { // DUPE: current_module_name_segments_count // TODO: strip shared prefixed between current module and imported // module to avoid descending and climbing back out again if package == self.module.type_info.package || package.is_empty() { // Same package match self.current_module_name_segments_count { - 1 => format!("./{module}.d.mts"), + 1 => eco_format!("./{module}.d.mts"), _ => { let prefix = "../".repeat(self.current_module_name_segments_count - 1); - format!("{prefix}{module}.d.mts") + eco_format!("{prefix}{module}.d.mts") } } } else { // Different package let prefix = "../".repeat(self.current_module_name_segments_count); - format!("{prefix}{package}/{module}.d.mts") + eco_format!("{prefix}{package}/{module}.d.mts") } } diff --git a/compiler-core/src/parse.rs b/compiler-core/src/parse.rs index 42ef9175c7b..7d02229c6ad 100644 --- a/compiler-core/src/parse.rs +++ b/compiler-core/src/parse.rs @@ -213,7 +213,7 @@ pub struct Parser> { tok0: Option, tok1: Option, extra: ModuleExtra, - doc_comments: VecDeque<(u32, String)>, + doc_comments: VecDeque<(u32, EcoString)>, } impl Parser where diff --git a/compiler-core/src/parse/lexer.rs b/compiler-core/src/parse/lexer.rs index 0015cac5fa6..b73e6c3a9d9 100644 --- a/compiler-core/src/parse/lexer.rs +++ b/compiler-core/src/parse/lexer.rs @@ -1,3 +1,5 @@ +use ecow::EcoString; + use crate::ast::SrcSpan; use crate::parse::error::{LexicalError, LexicalErrorType}; use crate::parse::token::Token; @@ -705,7 +707,7 @@ where } _ => Kind::Comment, }; - let mut content = String::new(); + let mut content = EcoString::new(); let start_pos = self.get_pos(); while Some('\n') != self.chr0 { match self.chr0 { diff --git a/compiler-core/src/parse/token.rs b/compiler-core/src/parse/token.rs index 22f3afe4ff1..60ed9e8c10a 100644 --- a/compiler-core/src/parse/token.rs +++ b/compiler-core/src/parse/token.rs @@ -10,7 +10,7 @@ pub enum Token { Int { value: EcoString }, Float { value: EcoString }, String { value: EcoString }, - CommentDoc { content: String }, + CommentDoc { content: EcoString }, // Groupings LeftParen, // ( RightParen, // ) diff --git a/compiler-core/src/pretty.rs b/compiler-core/src/pretty.rs index 5f261b92534..c4c4ddb0361 100644 --- a/compiler-core/src/pretty.rs +++ b/compiler-core/src/pretty.rs @@ -171,9 +171,9 @@ pub enum Document<'a> { /// Nests the given document to the current cursor position Group(Box), - /// A string to render - String { - string: String, + /// A str to render + Str { + string: &'a str, // The number of extended grapheme clusters in the string. // This is what the pretty printer uses as the width of the string as it // is closes to what a human would consider the "length" of a string. @@ -185,9 +185,6 @@ pub enum Document<'a> { graphemes: isize, }, - /// A str to render - Str { string: &'a str, graphemes: isize }, - /// A string that is cheap to copy EcoString { string: EcoString, graphemes: isize }, } @@ -329,9 +326,9 @@ fn fits( // When we run into a string we increase the current_width; looping // back we will check if we've exceeded the maximum allowed width. - Document::Str { graphemes, .. } - | Document::String { graphemes, .. } - | Document::EcoString { graphemes, .. } => current_width += graphemes, + Document::Str { graphemes, .. } | Document::EcoString { graphemes, .. } => { + current_width += graphemes + } // If we get to a break we need to first see if it has to be // rendered as its unbroken or broken string, depending on the mode. @@ -485,11 +482,6 @@ fn format( // Strings are printed as they are and the current width is // increased accordingly. - Document::String { string, graphemes } => { - width += graphemes; - writer.str_write(string)?; - } - Document::EcoString { string, graphemes } => { width += graphemes; writer.str_write(string)?; @@ -674,7 +666,6 @@ impl<'a> Document<'a> { match self { Line(n) => *n == 0, EcoString { string, .. } => string.is_empty(), - String { string, .. } => string.is_empty(), Str { string, .. } => string.is_empty(), // assuming `broken` and `unbroken` are equivalent Break { broken, .. } => broken.is_empty(),