Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiling improvements #591

Merged
merged 11 commits into from
Jan 12, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- (`lua52`) Support LuaJIT number suffixes LL/ULL/i ([#621](https://github.com/JohnnyMorganz/StyLua/issues/621))
- (`lua52`) Support `\z` escape sequences in strings ([#613](https://github.com/JohnnyMorganz/StyLua/issues/613))
- (`luau`) Support Luau string interpolation ([#607](https://github.com/JohnnyMorganz/StyLua/issues/607))
- Several optimisations applied to formatting functions to reduce time taken. Files which previously did not terminate (6MB+) now finish in reasonable time

## [0.15.3] - 2022-12-07

Expand Down
6 changes: 1 addition & 5 deletions src/formatters/assignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,7 @@ pub fn format_assignment_no_trivia(
// Check if the assignment expressions or equal token contain comments. If they do, we bail out of determining any tactics
// and format multiline
let contains_comments = trivia_util::token_contains_comments(assignment.equal_token())
|| assignment.expressions().pairs().any(|pair| {
pair.punctuation()
.map_or(false, trivia_util::token_contains_comments)
|| trivia_util::expression_contains_inline_comments(pair.value())
});
|| trivia_util::punctuated_expression_inline_comments(assignment.expressions());

// Firstly attempt to format the assignment onto a single line, using an infinite column width shape
let mut var_list = try_format_punctuated(
Expand Down
7 changes: 2 additions & 5 deletions src/formatters/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ pub fn format_return(ctx: &Context, return_node: &Return, shape: Shape) -> Retur
);

let contains_comments = return_token_trailing_comments
|| trivia_util::contains_comments(
returns.update_trailing_trivia(FormatTriviaType::Replace(Vec::new())), // We can ignore trailing trivia, as that won't affect anything
);
|| trivia_util::punctuated_expression_inline_comments(returns);

// See if we need to format multiline
// If we contain comments, we immediately force multiline, and return an empty Punctuated sequence as a placeholder (it will never be used)
Expand Down Expand Up @@ -590,8 +588,7 @@ pub fn format_block(ctx: &Context, block: &Block, shape: Shape) -> Block {
None => None,
};

block
.to_owned()
Block::new()
.with_stmts(formatted_statements)
.with_last_stmt(formatted_last_stmt)
}
20 changes: 10 additions & 10 deletions src/formatters/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,8 @@ pub fn format_table_constructor(

let (start_brace, end_brace) = table_constructor.braces().tokens();

// Determine if we need to force the table multiline
let should_expand = should_expand(ctx, table_constructor);

let table_type = match (should_expand, table_constructor.fields().iter().next()) {
// We should expand, so force multiline
(true, _) => TableType::MultiLine,

(false, Some(_)) => {
let table_type = match table_constructor.fields().iter().next() {
Some(_) => {
// Determine if there was a new line at the end of the start brace
// If so, then we should always be multiline
if start_brace
Expand Down Expand Up @@ -511,12 +505,18 @@ pub fn format_table_constructor(

match singleline_shape.over_budget() {
true => TableType::MultiLine,
false => TableType::SingleLine,
false => match should_expand(ctx, table_constructor) {
true => TableType::MultiLine,
false => TableType::SingleLine,
},
}
}
}

(false, None) => TableType::Empty,
None => match should_expand(ctx, table_constructor) {
true => TableType::MultiLine,
false => TableType::Empty,
},
};

let (braces, fields) = match table_type {
Expand Down
44 changes: 42 additions & 2 deletions src/formatters/trivia_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1222,8 +1222,9 @@ pub fn token_contains_comments(token: &TokenReference) -> bool {
token_contains_comments_search(token, CommentSearch::All)
}

/// CAUTION: VERY EXPENSIVE FUNCTION FOR LARGE NODES
pub fn contains_comments(node: impl Node) -> bool {
node.tokens().into_iter().any(token_contains_comments)
node.tokens().any(token_contains_comments)
}

#[allow(dead_code)]
Expand Down Expand Up @@ -1272,7 +1273,46 @@ pub fn table_field_trailing_trivia(field: &Field) -> Vec<Token> {
// This can only happen if the expression is a BinOp
// We should ignore any comments which are trailing for the whole expression, as they are not inline
pub fn expression_contains_inline_comments(expression: &Expression) -> bool {
contains_comments(expression.update_trailing_trivia(FormatTriviaType::Replace(vec![])))
match expression {
Expression::BinaryOperator { lhs, binop, rhs } => {
contains_comments(binop)
|| contains_comments(lhs)
|| expression_contains_inline_comments(rhs)
}
Expression::UnaryOperator { unop, expression } => {
let op_contains_comments = match unop {
UnOp::Minus(token) | UnOp::Not(token) | UnOp::Hash(token) => {
contains_comments(token)
}
#[cfg(feature = "lua53")]
UnOp::Tilde(token) => contains_comments(token),
other => panic!("unknown node {:?}", other),
};
op_contains_comments || expression_contains_inline_comments(expression)
}
Expression::Parentheses {
contained,
expression,
} => {
token_contains_trailing_comments(contained.tokens().0)
|| token_contains_leading_comments(contained.tokens().1)
|| contains_comments(expression)
}
Expression::Value { value, .. } => match &**value {
Value::ParenthesesExpression(expression) => {
expression_contains_inline_comments(expression)
}
_ => false,
},
other => panic!("unknown node {:?}", other),
}
}

pub fn punctuated_expression_inline_comments(punctuated: &Punctuated<Expression>) -> bool {
punctuated.pairs().any(|pair| {
pair.punctuation().map_or(false, token_contains_comments)
|| expression_contains_inline_comments(pair.value())
})
}

// Commonly, we update trivia to add in a newline and indent trivia to the leading trivia of a token/node.
Expand Down