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
31 changes: 24 additions & 7 deletions src/formatters/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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,
Expand All @@ -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))
})
}
}
Expand Down Expand Up @@ -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);

Expand Down
27 changes: 24 additions & 3 deletions src/formatters/general.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
Expand Down
22 changes: 22 additions & 0 deletions tests/inputs/function-call-multiline-comment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]]
)
Original file line number Diff line number Diff line change
Expand Up @@ -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
]]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting that it moves these outside of the comma, but maybe not a big deal?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tbh, I think the likelihood of a comment in this particular position (after expression but before the comma) is very low, so not sure it matters too much.

I moved it afterwards for simplicity, but I made an assumption here - let me see if it still works in its current position

--[[ frobnikate the widget ]]
false,
true
--[[ spin the tesla coils ]]
)