mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
refactor: remove needles string allocation in pretty printer
Many times, in order to create a `ven_pretty::Doc` containing a text node, the pattern `alloc.text(format!(...))` would be used. This code then creates a fresh string that is then used in the `Doc`. However, many times only a small string is necessary and so the allocation could be optimized. The `ven_pretty` crate supports this through a `SmallString` type. Allocating a fresh string with `format!` also moves control away from the `DocAllocator` which isn't ideal, since it could also handle the string allocations. So, instead of creating a fresh string, one can simply call `alloc.as_string(format_args!(...))` and delegate the allocation to the `DocAllocator` without any loss in expressivity. So, in order to encorage this pattern, this commit also introduces the `text!` macro. In order to find all instances of the code pattern, the following tree-sitter query was used: ```scm (call_expression function: (field_expression field: (field_identifier) @field.name (#eq? @field.name "text")) arguments: (arguments (macro_invocation macro: (identifier) @macro.name (#eq? @macro.name "format")))) @reference.call ```
This commit is contained in:
parent
d84a9fa8ba
commit
7d0027f428
8 changed files with 83 additions and 99 deletions
|
@ -9,7 +9,7 @@ use crate::pattern::{Pattern, RecordDestruct, TupleDestruct};
|
|||
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
|
||||
use ven_pretty::{Arena, DocAllocator, DocBuilder};
|
||||
use ven_pretty::{text, Arena, DocAllocator, DocBuilder};
|
||||
|
||||
pub struct Ctx<'a> {
|
||||
pub home: ModuleId,
|
||||
|
@ -163,10 +163,10 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
|||
use EPrec::*;
|
||||
match e {
|
||||
Num(_, n, _, _) | Int(_, _, n, _, _) | Float(_, _, n, _, _) => f.text(&**n),
|
||||
Str(s) => f.text(format!(r#""{}""#, s)),
|
||||
SingleQuote(_, _, c, _) => f.text(format!("'{}'", c)),
|
||||
Str(s) => text!(f, r#""{}""#, s),
|
||||
SingleQuote(_, _, c, _) => text!(f, "'{}'", c),
|
||||
IngestedFile(file_path, bytes, _) => {
|
||||
f.text(format!("<ingested {:?}, {} bytes>", file_path, bytes.len()))
|
||||
text!(f, "<ingested {:?}, {} bytes>", file_path, bytes.len())
|
||||
}
|
||||
List {
|
||||
elem_var: _,
|
||||
|
@ -354,15 +354,15 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
|||
RecordAccess {
|
||||
loc_expr, field, ..
|
||||
} => expr(c, AppArg, f, &loc_expr.value)
|
||||
.append(f.text(format!(".{}", field.as_str())))
|
||||
.append(text!(f, ".{}", field.as_str()))
|
||||
.group(),
|
||||
TupleAccess {
|
||||
loc_expr, index, ..
|
||||
} => expr(c, AppArg, f, &loc_expr.value)
|
||||
.append(f.text(format!(".{index}")))
|
||||
.append(text!(f, ".{index}"))
|
||||
.group(),
|
||||
OpaqueWrapFunction(OpaqueWrapFunctionData { opaque_name, .. }) => {
|
||||
f.text(format!("@{}", opaque_name.as_str(c.interns)))
|
||||
text!(f, "@{}", opaque_name.as_str(c.interns))
|
||||
}
|
||||
RecordAccessor(_) => todo!(),
|
||||
RecordUpdate {
|
||||
|
@ -436,11 +436,12 @@ fn pp_sym<'a>(c: &Ctx, f: &'a Arena<'a>, sym: Symbol) -> DocBuilder<'a, Arena<'a
|
|||
if sym.module_id() == c.home {
|
||||
f.text(sym.as_str(c.interns).to_owned())
|
||||
} else {
|
||||
f.text(format!(
|
||||
text!(
|
||||
f,
|
||||
"{}.{}",
|
||||
sym.module_string(c.interns),
|
||||
sym.as_str(c.interns),
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -516,8 +517,7 @@ fn pattern<'a>(
|
|||
),
|
||||
UnwrappedOpaque {
|
||||
opaque, argument, ..
|
||||
} => f
|
||||
.text(format!("@{} ", opaque.module_string(c.interns)))
|
||||
} => text!(f, "@{} ", opaque.module_string(c.interns))
|
||||
.append(pattern(c, Free, f, &argument.1.value))
|
||||
.group(),
|
||||
RecordDestructure { destructs, .. } => f
|
||||
|
@ -559,8 +559,8 @@ fn pattern<'a>(
|
|||
NumLiteral(_, n, _, _) | IntLiteral(_, _, n, _, _) | FloatLiteral(_, _, n, _, _) => {
|
||||
f.text(&**n)
|
||||
}
|
||||
StrLiteral(s) => f.text(format!(r#""{}""#, s)),
|
||||
SingleQuote(_, _, c, _) => f.text(format!("'{}'", c)),
|
||||
StrLiteral(s) => text!(f, r#""{}""#, s),
|
||||
SingleQuote(_, _, c, _) => text!(f, "'{}'", c),
|
||||
Underscore => f.text("_"),
|
||||
|
||||
Shadowed(_, _, _) => todo!(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue