From e8fc6911cec657757b1ba5851cdb4c80553dacbf Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Sun, 11 Sep 2022 16:05:10 +0100 Subject: [PATCH] Improve comments within function calls (#566) * Update test case * Expand call if it contains proper multiline comment * Update test case * Handle trailing comments on start parens * Add space after comment in start_parens * Handle leading comments on punctuation in Punctuated * Update snapshot --- src/formatters/functions.rs | 31 ++++++++++++++----- src/formatters/general.rs | 27 ++++++++++++++-- .../function-call-multiline-comment.lua | 22 +++++++++++++ ...d@function-call-multiline-comment.lua.snap | 22 +++++++++++++ 4 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/formatters/functions.rs b/src/formatters/functions.rs index d23798eb..9baf8fb6 100644 --- a/src/formatters/functions.rs +++ b/src/formatters/functions.rs @@ -5,7 +5,7 @@ use full_moon::ast::{ FunctionName, Index, LastStmt, LocalFunction, MethodCall, Parameter, Prefix, Stmt, Suffix, TableConstructor, Value, Var, }; -use full_moon::tokenizer::{Token, TokenReference, TokenType}; +use full_moon::tokenizer::{Token, TokenKind, TokenReference, TokenType}; use std::boxed::Box; #[cfg(feature = "luau")] @@ -95,6 +95,12 @@ fn is_complex_arg(value: &Value) -> bool { value.to_string().trim().contains('\n') } +// Test for singleline comments or multiline comments which span more than one line +fn function_trivia_contains_comments(trivia: &Token) -> bool { + matches!(trivia.token_kind(), TokenKind::SingleLineComment) + || matches!(trivia.token_type(), TokenType::MultiLineComment { comment, .. } if comment.as_str().lines().count() > 1 ) +} + /// Determines whether a parenthesised function call contains comments, forcing it to go multiline fn function_args_contains_comments( parentheses: &ContainedSpan, @@ -116,11 +122,11 @@ fn function_args_contains_comments( trivia_util::get_expression_leading_trivia(argument.value()) .iter() .chain(trivia_util::get_expression_trailing_trivia(argument.value()).iter()) - .any(trivia_util::trivia_is_singleline_comment) + .any(function_trivia_contains_comments) // Punctuation contains comments || argument .punctuation() - .map_or(false, |token| trivia_util::token_contains_comments_search(token, trivia_util::CommentSearch::Single)) + .map_or(false, |token| token.leading_trivia().chain(token.trailing_trivia()).any(function_trivia_contains_comments)) }) } } @@ -426,14 +432,25 @@ pub fn format_function_args( arguments, } } else { - // We don't need to worry about comments here, as if there were comments present, we would have - // multiline function args - // If we are hugging a table constructor with the parentheses, we use a shape increment of 2 to include the closing // parentheses as well. Otherwise, we just use 1 = opening parentheses. let shape_increment = if hug_table_constructor { 2 } else { 1 }; - let parentheses = format_contained_span(ctx, parentheses, shape); + let (start_parens, end_parens) = parentheses.tokens(); + let start_parens = format_token_reference(ctx, start_parens, shape); + let start_parens = if trivia_util::token_contains_trailing_comments(&start_parens) + && !arguments.is_empty() + { + start_parens.update_trailing_trivia(FormatTriviaType::Append(vec![Token::new( + TokenType::spaces(1), + )])) + } else { + start_parens + }; + + let end_parens = format_token_reference(ctx, end_parens, shape); + let parentheses = ContainedSpan::new(start_parens, end_parens); + let mut arguments = format_punctuated(ctx, arguments, shape + shape_increment, format_expression); diff --git a/src/formatters/general.rs b/src/formatters/general.rs index 74bbdeda..51eac1ba 100644 --- a/src/formatters/general.rs +++ b/src/formatters/general.rs @@ -14,6 +14,8 @@ use full_moon::ast::{ use full_moon::node::Node; use full_moon::tokenizer::{StringLiteralQuoteType, Token, TokenKind, TokenReference, TokenType}; +use super::trivia::UpdateTrivia; + #[derive(Debug, Clone, Copy)] pub enum FormatTokenType { Token, @@ -496,9 +498,28 @@ where Some(punctuation) => { // Continue adding a comma and a new line for multiline function args // Also add any trailing comments we have taken from the expression - trailing_comments.push(create_newline_trivia(ctx)); - let symbol = fmt_symbol!(ctx, punctuation, ",", shape) - .update_trailing_trivia(FormatTriviaType::Append(trailing_comments)); + let symbol = fmt_symbol!(ctx, punctuation, ",", shape); + + let mut trailing_trivia: Vec<_> = symbol + .leading_trivia() + .filter(|trivia| trivia_util::trivia_is_comment(trivia)) + .cloned() + .flat_map(|x| { + // Prepend a single space beforehand + vec![ + create_newline_trivia(ctx), + create_indent_trivia(ctx, shape), + x, + ] + }) + .collect(); + trailing_trivia.append(&mut trailing_comments); + trailing_trivia.push(create_newline_trivia(ctx)); + + let symbol = symbol.update_trivia( + FormatTriviaType::Replace(vec![]), + FormatTriviaType::Append(trailing_trivia), + ); Some(symbol) } diff --git a/tests/inputs/function-call-multiline-comment.lua b/tests/inputs/function-call-multiline-comment.lua index b5463e54..31acc6a6 100644 --- a/tests/inputs/function-call-multiline-comment.lua +++ b/tests/inputs/function-call-multiline-comment.lua @@ -2,3 +2,25 @@ -- no need to expand call(item, --[[param=]] false) + +call(--[[ we don't use it ]]true) + +call( + --[[ + this comment spans + multiple lines + ]] + false +) + +x( + true, + 90210 + --[[ + color wheel is time-reversed + ]], + --[[ frobnikate the widget ]] + false, + true + --[[ spin the tesla coils ]] +) diff --git a/tests/snapshots/tests__standard@function-call-multiline-comment.lua.snap b/tests/snapshots/tests__standard@function-call-multiline-comment.lua.snap index 71318c8e..d4444892 100644 --- a/tests/snapshots/tests__standard@function-call-multiline-comment.lua.snap +++ b/tests/snapshots/tests__standard@function-call-multiline-comment.lua.snap @@ -7,3 +7,25 @@ expression: format(&contents) call(item, --[[param=]] false) +call(--[[ we don't use it ]] true) + +call( + --[[ + this comment spans + multiple lines + ]] + false +) + +x( + true, + 90210, + --[[ + color wheel is time-reversed + ]] + --[[ frobnikate the widget ]] + false, + true + --[[ spin the tesla coils ]] +) +