diff --git a/CHANGELOG.md b/CHANGELOG.md index c606d4d1..8f31bb31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Correct indentation for a documented function defined as table value ([#942](https://github.com/JohnnyMorganz/StyLua/issues/942)) + +```lua +local t = { + plus_one = + ---@param n number + ---@return number + function(n) + return n + 1 + end, +} +``` + ### Added - Luau: Added support for parsing user-defined type functions ([#938](https://github.com/JohnnyMorganz/StyLua/issues/938)) diff --git a/src/formatters/table.rs b/src/formatters/table.rs index 6c31f7a8..b82e8e03 100644 --- a/src/formatters/table.rs +++ b/src/formatters/table.rs @@ -34,7 +34,20 @@ pub enum TableType { Empty, } +/// Detect function with leading comments/doc-comments when used as a table value +/// Such (anonymous) function definition gets formatted differently, in a separate line line +fn is_function_with_leading_trivia(expression: &Expression) -> bool { + match expression { + Expression::Function(anonymous_function) => { + !trivia_util::GetLeadingTrivia::leading_trivia(&anonymous_function.0).is_empty() + } + _ => false, + } +} + /// Formats an Expression value part of a k,v field pair +/// If value is an anonymous function with trivia, will prepend a newline so the trivia will align +/// to the function definition fn format_field_expression_value( ctx: &Context, expression: &Expression, @@ -64,6 +77,14 @@ fn format_field_expression_value( } } } else { + if is_function_with_leading_trivia(expression) { + let incr_shape = shape.increment_additional_indent(); + let incr_leading_trivia = vec![create_indent_trivia(ctx, incr_shape)]; + let formatted_expr = format_expression(ctx, expression, incr_shape) + .update_trailing_trivia(trailing_trivia) + .update_leading_trivia(FormatTriviaType::Append(incr_leading_trivia)); + return trivia_util::prepend_newline_indent(ctx, &formatted_expr, incr_shape); + } format_expression(ctx, expression, shape).update_trailing_trivia(trailing_trivia) } } @@ -205,6 +226,15 @@ fn format_field( let shape = shape + (strip_trivia(&key).to_string().len() + 3); // 3 = " = " let value = format_field_expression_value(ctx, value, shape); + let equal = if is_function_with_leading_trivia(&value) { + // function definition goes in the next line, so we remove space between = and newline + equal.update_trailing_trivia(FormatTriviaType::Replace(vec![Token::new( + TokenType::spaces(0), + )])) + } else { + equal + }; + Field::NameKey { key, equal, value } } Field::NoKey(expression) => { diff --git a/tests/inputs/function-as-table-value-in-mixed-def.lua b/tests/inputs/function-as-table-value-in-mixed-def.lua new file mode 100644 index 00000000..e480a214 --- /dev/null +++ b/tests/inputs/function-as-table-value-in-mixed-def.lua @@ -0,0 +1,14 @@ +local mixed = { + --- identity + ---@param n number + ---@return number + function(n) + return n + end, + plus_one = + ---@param n number + ---@return number + function(n) + return n + 1 + end, +} diff --git a/tests/inputs/function-as-table-value.lua b/tests/inputs/function-as-table-value.lua new file mode 100644 index 00000000..9e58efcf --- /dev/null +++ b/tests/inputs/function-as-table-value.lua @@ -0,0 +1,9 @@ +-- https://github.com/JohnnyMorganz/StyLua/issues/942 +local t = { + plus_one = + ---@param n number + ---@return number + function(n) + return n + 1 + end, +} diff --git a/tests/snapshots/tests__standard@function-as-table-value-in-mixed-def.lua.snap b/tests/snapshots/tests__standard@function-as-table-value-in-mixed-def.lua.snap new file mode 100644 index 00000000..eb02af8f --- /dev/null +++ b/tests/snapshots/tests__standard@function-as-table-value-in-mixed-def.lua.snap @@ -0,0 +1,21 @@ +--- +source: tests/tests.rs +assertion_line: 21 +expression: "format(&contents, LuaVersion::Lua51)" +input_file: tests/inputs/function-as-table-value-in-mixed-def.lua +--- +local mixed = { + --- identity + ---@param n number + ---@return number + function(n) + return n + end, + plus_one = + ---@param n number + ---@return number + function(n) + return n + 1 + end, +} + diff --git a/tests/snapshots/tests__standard@function-as-table-value.lua.snap b/tests/snapshots/tests__standard@function-as-table-value.lua.snap new file mode 100644 index 00000000..6df07b1b --- /dev/null +++ b/tests/snapshots/tests__standard@function-as-table-value.lua.snap @@ -0,0 +1,16 @@ +--- +source: tests/tests.rs +assertion_line: 18 +expression: "format(&contents, LuaVersion::Lua51)" +input_file: tests/inputs/function-as-table-value.lua +--- +-- https://github.com/JohnnyMorganz/StyLua/issues/942 +local t = { + plus_one = + ---@param n number + ---@return number + function(n) + return n + 1 + end, +} +