From 192335748bc29636f760a6eda9c6857d4f5afe37 Mon Sep 17 00:00:00 2001 From: Jon Egeland Date: Tue, 12 Dec 2023 06:04:12 +0000 Subject: [PATCH] also fix is_simple_ts_type --- .../src/js/expressions/call_arguments.rs | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/crates/biome_js_formatter/src/js/expressions/call_arguments.rs b/crates/biome_js_formatter/src/js/expressions/call_arguments.rs index 5cddaf608d40..0c2314e9742b 100644 --- a/crates/biome_js_formatter/src/js/expressions/call_arguments.rs +++ b/crates/biome_js_formatter/src/js/expressions/call_arguments.rs @@ -874,11 +874,48 @@ fn should_group_last_argument( /// HTMLElement => true /// string | object => false /// Foo => false -/// -/// Note that Prettier allows extracting the inner type from arrays and -/// single-argument generic types, but for now, this implementation does not. -fn is_simple_ts_type(ty: AnyTsType) -> bool { - match ty { +/// This function also introspects into array and generic types to extract the +/// core type, but only to a limited extent: +/// string[] => string +/// string[][] => string +/// string[][][] => string +/// Foo[][] => string +/// Foo[] => string[] +/// Foo => string[][] +fn is_simple_ts_type(ty: &AnyTsType) -> bool { + // Reach up to two-levels deep into array types: + // string[] => string + // string[][] => string + // string[][][] => string[] + let extracted_array_type = match ty { + AnyTsType::TsArrayType(array) => match array.element_type() { + Ok(AnyTsType::TsArrayType(inner_array)) => inner_array.element_type().ok(), + Ok(element_type) => Some(element_type), + _ => None, + }, + _ => None, + }; + + // Then, extract the first type parameter of a Generic as long as it's the + // only parameter: + // Foo => number + // Foo => Foo + let extracted_generic_type = match &extracted_array_type { + Some(AnyTsType::TsReferenceType(generic)) => { + generic.type_arguments().map_or(None, |type_arguments| { + let argument_list = type_arguments.ts_type_argument_list(); + if argument_list.len() == 1 { + argument_list.first().map_or(None, |first| first.ok()) + } else { + extracted_array_type + } + }) + } + _ => extracted_array_type, + }; + + let resolved_type = extracted_generic_type.as_ref().unwrap_or(ty); + match resolved_type { // Any keyword or literal types AnyTsType::TsAnyType(_) | AnyTsType::TsBigintLiteralType(_) @@ -941,7 +978,7 @@ fn is_relatively_short_argument(argument: AnyJsExpression) -> bool { ty: Ok(annotation), } = as_expression.as_fields() { - is_simple_ts_type(annotation) && SimpleArgument::from(expression).is_simple() + is_simple_ts_type(&annotation) && SimpleArgument::from(expression).is_simple() } else { false } @@ -953,7 +990,7 @@ fn is_relatively_short_argument(argument: AnyJsExpression) -> bool { ty: Ok(annotation), } = as_expression.as_fields() { - is_simple_ts_type(annotation) && SimpleArgument::from(expression).is_simple() + is_simple_ts_type(&annotation) && SimpleArgument::from(expression).is_simple() } else { false }