From 55c0a9db3d4b0aac3abfc2a2b45a6a9cd3b477d9 Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Mon, 11 Apr 2022 17:49:18 +0100 Subject: [PATCH 1/5] Add test case --- tests/inputs-luau/excess-parentheses.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/inputs-luau/excess-parentheses.lua b/tests/inputs-luau/excess-parentheses.lua index 167bf603..947480b1 100644 --- a/tests/inputs-luau/excess-parentheses.lua +++ b/tests/inputs-luau/excess-parentheses.lua @@ -17,3 +17,14 @@ self.mutationStore[mutationId] = ( ) :: MutationStoreValue local _name = debug.info(fn :: ((any) -> any), "n") + +-- https://github.com/JohnnyMorganz/StyLua/issues/441 +if string.len(string_) > (length :: number) then + return string_:sub(1, (length :: number) + 1) .. "…" +else + return string_ +end + +if fiber.actualStartTime ~= nil and (fiber.actualStartTime :: number) < 0 then + fiber.actualStartTime = now() +end From 21ac5af99b672629b82dc59333d412081cc31e7c Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Mon, 11 Apr 2022 17:54:06 +0100 Subject: [PATCH 2/5] Keep parens around type assertion if in binexp --- src/formatters/expression.rs | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/formatters/expression.rs b/src/formatters/expression.rs index 0d23baca..4b2422c6 100644 --- a/src/formatters/expression.rs +++ b/src/formatters/expression.rs @@ -59,7 +59,7 @@ enum ExpressionContext { TypeAssertion, /// The internal expression is having a unary operation applied to it: the `expr` part of #expr. /// If this occurs, and `expr` is a type assertion, then we need to keep the parentheses - Unary, + UnaryOrBinary, } pub fn format_binop(ctx: &Context, binop: &BinOp, shape: Shape) -> BinOp { @@ -99,11 +99,11 @@ fn check_excess_parentheses(internal_expression: &Expression, context: Expressio #[cfg(feature = "luau")] type_assertion, } => { - // If we have a type assertion, and the context is a unary operation + // If we have a type assertion, and the context is a unary or binary operation // we should always keep parentheses // [e.g. #(value :: Array) or -(value :: number)] #[cfg(feature = "luau")] - if type_assertion.is_some() && matches!(context, ExpressionContext::Unary) { + if type_assertion.is_some() && matches!(context, ExpressionContext::UnaryOrBinary) { return false; } @@ -208,8 +208,12 @@ fn format_expression_internal( Expression::UnaryOperator { unop, expression } => { let unop = format_unop(ctx, unop, shape); let shape = shape + strip_leading_trivia(&unop).to_string().len(); - let mut expression = - format_expression_internal(ctx, expression, ExpressionContext::Unary, shape); + let mut expression = format_expression_internal( + ctx, + expression, + ExpressionContext::UnaryOrBinary, + shape, + ); // Special case: if we have `- -foo`, or `-(-foo)` where we have already removed the parentheses, then // it will lead to `--foo`, which is invalid syntax. We must explicitly add/keep the parentheses `-(-foo)`. @@ -251,13 +255,18 @@ fn format_expression_internal( } } Expression::BinaryOperator { lhs, binop, rhs } => { - let lhs = format_expression(ctx, lhs, shape); + let lhs = format_expression_internal(ctx, lhs, ExpressionContext::UnaryOrBinary, shape); let binop = format_binop(ctx, binop, shape); let shape = shape.take_last_line(&lhs) + binop.to_string().len(); Expression::BinaryOperator { lhs: Box::new(lhs), binop, - rhs: Box::new(format_expression(ctx, rhs, shape)), + rhs: Box::new(format_expression_internal( + ctx, + rhs, + ExpressionContext::UnaryOrBinary, + shape, + )), } } other => panic!("unknown node {:?}", other), @@ -1032,10 +1041,20 @@ fn hang_binop_expression( lhs_shape, lhs_range, ), - format_expression(ctx, &*rhs, rhs_shape), + format_expression_internal( + ctx, + &*rhs, + ExpressionContext::UnaryOrBinary, + rhs_shape, + ), ), ExpressionSide::Right => ( - format_expression(ctx, &*lhs, lhs_shape), + format_expression_internal( + ctx, + &*lhs, + ExpressionContext::UnaryOrBinary, + lhs_shape, + ), hang_binop_expression( ctx, *rhs, @@ -1056,13 +1075,13 @@ fn hang_binop_expression( let lhs = if contains_comments(&*lhs) { hang_binop_expression(ctx, *lhs, binop.to_owned(), shape, lhs_range) } else { - format_expression(ctx, &*lhs, shape) + format_expression_internal(ctx, &*lhs, ExpressionContext::UnaryOrBinary, shape) }; let rhs = if contains_comments(&*rhs) { hang_binop_expression(ctx, *rhs, binop, shape, lhs_range) } else { - format_expression(ctx, &*rhs, shape) + format_expression_internal(ctx, &*rhs, ExpressionContext::UnaryOrBinary, shape) }; (lhs, rhs) @@ -1223,7 +1242,7 @@ fn format_hanging_expression_( ctx, expression, shape, - ExpressionContext::Unary, + ExpressionContext::UnaryOrBinary, lhs_range, ); From e7c07158dbc6dc293a57970251c64dfa7289377a Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Mon, 11 Apr 2022 17:54:11 +0100 Subject: [PATCH 3/5] Update test --- .../snapshots/tests__luau@excess-parentheses.lua.snap | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/snapshots/tests__luau@excess-parentheses.lua.snap b/tests/snapshots/tests__luau@excess-parentheses.lua.snap index 0aad9ca7..385ed5db 100644 --- a/tests/snapshots/tests__luau@excess-parentheses.lua.snap +++ b/tests/snapshots/tests__luau@excess-parentheses.lua.snap @@ -24,3 +24,14 @@ self.mutationStore[mutationId] = ( local _name = debug.info(fn :: ((any) -> any), "n") +-- https://github.com/JohnnyMorganz/StyLua/issues/441 +if string.len(string_) > (length :: number) then + return string_:sub(1, (length :: number) + 1) .. "…" +else + return string_ +end + +if fiber.actualStartTime ~= nil and (fiber.actualStartTime :: number) < 0 then + fiber.actualStartTime = now() +end + From c2303a214cc12ff35b6e0454c24c272b194f5844 Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Mon, 11 Apr 2022 17:54:49 +0100 Subject: [PATCH 4/5] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24539579..0e6dce7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed unstable formatting of tables at column width boundary ([#436](https://github.com/JohnnyMorganz/StyLua/issues/436)) - Fixed assignments no longer hanging at equals token if a comment is present, but the expression is not hangable at a binop. ([#439](https://github.com/JohnnyMorganz/StyLua/issues/439)) - Fixed unstable formatting around comments within type declarations ([#397](https://github.com/JohnnyMorganz/StyLua/issues/397), [#430](https://github.com/JohnnyMorganz/StyLua/issues/430)) +- Fixed parentheses around type assertions in a binary expression being removed leading to incorrect semantics. ([#441](https://github.com/JohnnyMorganz/StyLua/issues/441)) ## [0.13.0] - 2022-03-31 ### Added From fdd5b20c748dd7c5147da17eb66463ebb02fe625 Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Mon, 11 Apr 2022 18:04:13 +0100 Subject: [PATCH 5/5] Rustfmt --- src/formatters/expression.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/formatters/expression.rs b/src/formatters/expression.rs index 4b2422c6..9544836b 100644 --- a/src/formatters/expression.rs +++ b/src/formatters/expression.rs @@ -1075,13 +1075,23 @@ fn hang_binop_expression( let lhs = if contains_comments(&*lhs) { hang_binop_expression(ctx, *lhs, binop.to_owned(), shape, lhs_range) } else { - format_expression_internal(ctx, &*lhs, ExpressionContext::UnaryOrBinary, shape) + format_expression_internal( + ctx, + &*lhs, + ExpressionContext::UnaryOrBinary, + shape, + ) }; let rhs = if contains_comments(&*rhs) { hang_binop_expression(ctx, *rhs, binop, shape, lhs_range) } else { - format_expression_internal(ctx, &*rhs, ExpressionContext::UnaryOrBinary, shape) + format_expression_internal( + ctx, + &*rhs, + ExpressionContext::UnaryOrBinary, + shape, + ) }; (lhs, rhs)