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
59 changes: 29 additions & 30 deletions Cargo.lock

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

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "dprint-plugin-typescript"
version = "0.95.12"
authors = ["David Sherret <dsherret@gmail.com>"]
edition = "2021"
edition = "2024"
homepage = "https://github.com/dprint/dprint-plugin-typescript"
keywords = ["formatting", "formatter", "typescript", "javascript"]
license = "MIT"
Expand Down Expand Up @@ -32,7 +32,7 @@ harness = false
[dependencies]
anyhow = "1.0.64"
capacity_builder = "0.5.0"
deno_ast = { version = "0.51.0", features = ["view"] }
deno_ast = { version = "0.52.0", features = ["view"] }
dprint-core = { version = "0.67.4", features = ["formatting"] }
dprint-core-macros = "0.1.0"
percent-encoding = "2.3.1"
Expand All @@ -47,4 +47,3 @@ malva = "0.11.2"
markup_fmt = "0.19.0"
pretty_assertions = "1.3.0"
serde_json = { version = "1.0" }

2 changes: 1 addition & 1 deletion src/format_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fn inner_format(parsed_source: &ParsedSource, config: &Configuration, external_f
pub fn trace_file(file_path: &Path, file_text: &str, config: &Configuration) -> dprint_core::formatting::TracingResult {
let parsed_source = parse_swc_ast(file_path, None, file_text.into()).unwrap();
ensure_no_specific_syntax_errors(&parsed_source).unwrap();
dprint_core::formatting::trace_printing(|| generate(&parsed_source, config, None), config_to_print_options(file_text, config))
dprint_core::formatting::trace_printing(|| generate(&parsed_source, config, None).unwrap(), config_to_print_options(file_text, config))
}

fn config_to_print_options(file_text: &str, config: &Configuration) -> PrintOptions {
Expand Down
35 changes: 26 additions & 9 deletions src/generation/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3639,7 +3639,15 @@ fn gen_property_signature<'a>(node: &TsPropertySignature<'a>, context: &mut Cont
fn gen_quotable_prop<'a>(node: Node<'a>, context: &mut Context<'a>) -> PrintItems {
match context.config.quote_props {
QuoteProps::AsNeeded => match node {
Node::Str(str_lit) if is_text_valid_identifier(str_lit.value()) => gen_from_raw_string(str_lit.value()),
Node::Str(str_lit) => {
if let Some(text) = str_lit.value().as_str()
&& is_text_valid_identifier(text)
{
gen_from_raw_string(text)
} else {
gen_node(node, context)
}
}
_ => gen_node(node, context),
},
QuoteProps::Consistent => match context.use_consistent_quote_props() {
Expand All @@ -3651,7 +3659,10 @@ fn gen_quotable_prop<'a>(node: Node<'a>, context: &mut Context<'a>) -> PrintItem
},
Some(false) => match node {
// remove quotes
Node::Str(str_lit) => gen_from_raw_string(str_lit.value()),
Node::Str(str_lit) => match str_lit.value().as_str() {
Some(text) => gen_from_raw_string(text),
None => gen_node(node, context),
},
_ => gen_node(node, context),
},
None => {
Expand Down Expand Up @@ -3698,15 +3709,21 @@ fn use_consistent_quotes_for_members<'a>(mut members: impl Iterator<Item = Node<
fn check_expr(expr: Expr) -> bool {
match expr {
Expr::Ident(ident) => !is_text_valid_identifier(ident.sym()),
Expr::Lit(Lit::Str(str)) => !is_text_valid_identifier(str.value()),
Expr::Lit(Lit::Str(str)) => match str.value().as_str() {
Some(text) => !is_text_valid_identifier(text),
None => true,
},
_ => false,
}
}

fn check_prop_name(name: PropName) -> bool {
match name {
PropName::Ident(ident) => !is_text_valid_identifier(ident.sym()),
PropName::Str(str) => !is_text_valid_identifier(str.value()),
PropName::Str(str) => match str.value().as_str() {
Some(text) => !is_text_valid_identifier(text),
None => true,
},
_ => false,
}
}
Expand Down Expand Up @@ -9117,7 +9134,7 @@ fn gen_jsx_children<'a>(opts: GenJsxChildrenOptions<'a>, context: &mut Context<'
let mut found_non_space_child = false; // include space expressions at the start

for child in real_children.into_iter() {
if found_non_space_child && node_helpers::has_jsx_space_expr_text(child) {
if found_non_space_child && node_helpers::has_jsx_space_expr_text(child, context.program) {
current_jsx_space_exprs.push(child);
continue;
}
Expand Down Expand Up @@ -9239,19 +9256,19 @@ fn gen_jsx_children<'a>(opts: GenJsxChildrenOptions<'a>, context: &mut Context<'

/// If the node has a "JSX space expression" between or text that's only spaces between.
fn has_jsx_space_between<'a>(previous_node: Node<'a>, next_node: Node<'a>, program: Program<'a>) -> bool {
return node_helpers::nodes_have_only_spaces_between(previous_node, next_node, program) || has_jsx_space_expr_between(previous_node, next_node);

fn has_jsx_space_expr_between(previous_node: Node, next_node: Node) -> bool {
fn has_jsx_space_expr_between(previous_node: Node, next_node: Node, program: Program) -> bool {
let nodes_between = node_helpers::get_siblings_between(previous_node, next_node);

for node_between in nodes_between {
if node_helpers::has_jsx_space_expr_text(node_between) {
if node_helpers::has_jsx_space_expr_text(node_between, program) {
return true;
}
}

false
}

node_helpers::nodes_have_only_spaces_between(previous_node, next_node, program) || has_jsx_space_expr_between(previous_node, next_node, program)
}
}

Expand Down
21 changes: 16 additions & 5 deletions src/generation/node_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ pub fn get_siblings_between<'a, 'b>(node_a: Node<'a>, node_b: Node<'b>) -> Vec<N
parent_children.drain(node_a.child_index() + 1..node_b.child_index()).collect()
}

pub fn has_jsx_space_expr_text(node: Node) -> bool {
get_jsx_space_expr_space_count(node) > 0
pub fn has_jsx_space_expr_text(node: Node, program: Program) -> bool {
get_jsx_space_expr_space_count(node, program) > 0
}

pub fn get_jsx_space_expr_space_count(node: Node) -> usize {
pub fn get_jsx_space_expr_space_count(node: Node, program: Program) -> usize {
// A "JSX space expression" is a JSXExprContainer with
// a string literal containing only spaces.
// * {" "}
Expand All @@ -130,7 +130,8 @@ pub fn get_jsx_space_expr_space_count(node: Node) -> usize {
..
}) => {
let mut space_count = 0;
for c in text.value().chars() {
let text = remove_quotes_from_str(text.text_fast(program));
for c in text.chars() {
if c == ' ' {
space_count += 1;
} else {
Expand All @@ -143,6 +144,16 @@ pub fn get_jsx_space_expr_space_count(node: Node) -> usize {
}
}

fn remove_quotes_from_str(text: &str) -> &str {
if text.is_empty() {
text
} else if text.starts_with("'") && text.ends_with("'") || text.starts_with("\"") && text.ends_with("\"") {
&text[1..text.len() - 1]
} else {
text
}
}

pub fn count_spaces_between_jsx_children<'a>(previous_node: Node<'a>, next_node: Node<'a>, program: Program<'a>) -> usize {
let all_siblings_between = get_siblings_between(previous_node, next_node);
let siblings_between = all_siblings_between
Expand All @@ -155,7 +166,7 @@ pub fn count_spaces_between_jsx_children<'a>(previous_node: Node<'a>, next_node:
let mut previous_node = previous_node;

for node in siblings_between {
count += get_jsx_space_expr_space_count(node);
count += get_jsx_space_expr_space_count(node, program);

if nodes_have_only_spaces_between(previous_node, node, program) {
count += 1;
Expand Down
2 changes: 2 additions & 0 deletions tests/specs/literals/StringLiteral/StringLiteral_All.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
const t = "\t" ;
const u = "";
const v = "1";
const w = "\uD800";

[expect]
const t = "\t";
const u = "";
const v = "1";
const w = "\uD800";

== should not replace actual character with escaped character ==
const t = " ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,15 @@ const x = {
}),
"/src/shared/index.ts": `export const a: Unrestricted = 1;`,
};

== should add quotes for this ==
const objectLiteral = {
"\uD800": true,
test: 1,
};

[expect]
const objectLiteral = {
"\uD800": true,
"test": 1,
};