Skip to content

Commit a3cc920

Browse files
CppCXYCopilot
andcommitted
fix some format bug
Co-authored-by: Copilot <copilot@github.com>
1 parent 54b7d19 commit a3cc920

5 files changed

Lines changed: 242 additions & 19 deletions

File tree

crates/emmylua_formatter/src/formatter/expr.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ fn format_binary_expr(
137137
return docs;
138138
}
139139

140+
if should_attach_short_binary_tail(op_token.get_op(), &right, &right_docs)
141+
&& should_attach_after_multiline_left_expr(&left)
142+
{
143+
let mut docs = left_docs;
144+
if force_space_before {
145+
docs.push(ir::space());
146+
} else {
147+
docs.push(space_rule.to_ir());
148+
}
149+
docs.push(ir::source_token(op_token.syntax().clone()));
150+
docs.push(space_rule.to_ir());
151+
docs.extend(right_docs);
152+
return docs;
153+
}
154+
140155
vec![ir::group(vec![
141156
ir::list(left_docs),
142157
ir::indent(vec![
@@ -238,6 +253,18 @@ fn should_attach_short_binary_tail(
238253
}
239254
}
240255

256+
fn should_attach_after_multiline_left_expr(left: &LuaExpr) -> bool {
257+
left.syntax().text().contains_char('\n')
258+
&& matches!(
259+
left,
260+
LuaExpr::CallExpr(_)
261+
| LuaExpr::ParenExpr(_)
262+
| LuaExpr::IndexExpr(_)
263+
| LuaExpr::TableExpr(_)
264+
| LuaExpr::ClosureExpr(_)
265+
)
266+
}
267+
241268
fn format_unary_expr(
242269
ctx: &FormatContext,
243270
plan: &RootFormatPlan,
@@ -2477,7 +2504,7 @@ fn format_call_suffix_ir(
24772504
return docs;
24782505
}
24792506

2480-
let docs = if !args_list.syntax().text().contains_char('\n') {
2507+
if !args_list.syntax().text().contains_char('\n') {
24812508
match format_compact_call_arg_list(ctx, plan, &args_list, &args) {
24822509
CompactCallArgListAttempt::Formatted(docs) => docs,
24832510
CompactCallArgListAttempt::ReuseDocs(arg_docs) => {
@@ -2497,23 +2524,6 @@ fn format_call_suffix_ir(
24972524
}
24982525
} else {
24992526
format_call_arg_list(ctx, plan, &args_list)
2500-
};
2501-
2502-
let is_single_multiline_table_payload = args.len() == 1
2503-
&& matches!(args.first(), Some(LuaExpr::TableExpr(table)) if table.syntax().text().contains_char('\n'));
2504-
2505-
let has_multiline_block_payload = args.iter().any(|arg| {
2506-
matches!(arg, LuaExpr::ClosureExpr(_) | LuaExpr::TableExpr(_))
2507-
&& arg.syntax().text().contains_char('\n')
2508-
});
2509-
2510-
if ir::ir_has_forced_line_break(&docs)
2511-
&& !is_single_multiline_table_payload
2512-
&& !has_multiline_block_payload
2513-
{
2514-
vec![ir::indent(docs)]
2515-
} else {
2516-
docs
25172527
}
25182528
}
25192529

crates/emmylua_formatter/src/formatter/render/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,15 @@ fn normalize_single_normal_comment_line(
17751775
}
17761776
});
17771777
let body = body_with_gap.trim_start();
1778+
if prefix.trim_end() == "--"
1779+
&& body_with_gap
1780+
.chars()
1781+
.next()
1782+
.is_some_and(char::is_whitespace)
1783+
&& body.starts_with('[')
1784+
{
1785+
return format!("-- {body}");
1786+
}
17781787
if body.is_empty() {
17791788
prefix.trim_end().to_string()
17801789
} else {

crates/emmylua_formatter/src/formatter/spacing.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,10 @@ fn apply_comment_start_spacing(
364364
token: &LuaSyntaxToken,
365365
syntax_id: LuaSyntaxId,
366366
) {
367+
if comment_start_looks_like_spaced_long_comment(token) {
368+
return;
369+
}
370+
367371
if let Some(replacement) = normalized_comment_prefix(ctx, token.text()) {
368372
spacing.add_token_replace(syntax_id, replacement);
369373
spacing.add_token_right_expected(syntax_id, TokenSpacingExpected::Space(0));
@@ -457,6 +461,27 @@ fn get_prev_sibling_token_without_space(token: &LuaSyntaxToken) -> Option<LuaSyn
457461
None
458462
}
459463

464+
fn comment_start_looks_like_spaced_long_comment(token: &LuaSyntaxToken) -> bool {
465+
if token.kind().to_token() != LuaTokenKind::TkNormalStart || token.text() != "--" {
466+
return false;
467+
}
468+
469+
let mut current = token.next_token();
470+
let mut saw_whitespace = false;
471+
while let Some(next) = current {
472+
match next.kind().to_token() {
473+
LuaTokenKind::TkWhitespace => {
474+
saw_whitespace = true;
475+
current = next.next_token();
476+
}
477+
LuaTokenKind::TkEndOfLine => return false,
478+
_ => return saw_whitespace && next.text().starts_with('['),
479+
}
480+
}
481+
482+
false
483+
}
484+
460485
fn normalized_comment_prefix(ctx: &FormatContext, prefix_text: &str) -> Option<String> {
461486
match dash_prefix_len(prefix_text) {
462487
2 => Some(if ctx.config.comments.space_after_comment_dash {
@@ -652,6 +677,22 @@ mod tests {
652677
);
653678
}
654679

680+
#[test]
681+
fn test_spacing_does_not_normalize_spaced_long_comment_prefix() {
682+
let config = LuaFormatConfig::default();
683+
let tree = LuaParser::parse(
684+
"-- [[ not a long comment ]]\n",
685+
ParserConfig::with_level(LuaLanguageLevel::Lua54),
686+
);
687+
let chunk = tree.get_chunk_node();
688+
let spacing = analyze_root_spacing(&FormatContext::new(&config), &chunk).spacing;
689+
let start = find_token(&chunk, LuaTokenKind::TkNormalStart);
690+
let start_id = LuaSyntaxId::from_token(&start);
691+
692+
assert_eq!(spacing.token_replace(start_id), None);
693+
assert_eq!(spacing.right_expected(start_id), None);
694+
}
695+
655696
#[test]
656697
fn test_spacing_collects_doc_prefix_replacement() {
657698
let config = LuaFormatConfig::default();

crates/emmylua_formatter/src/test/comment_tests.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,18 @@ local a = 1
20982098
"#,
20992099
r#"--[[ some content ]]
21002100
local a = 1
2101+
"#
2102+
);
2103+
}
2104+
2105+
#[test]
2106+
fn test_spaced_long_comment_prefix_preserved_as_normal_comment() {
2107+
assert_format!(
2108+
r#"-- [[ some content ]]
2109+
local a = 1
2110+
"#,
2111+
r#"-- [[ some content ]]
2112+
local a = 1
21012113
"#
21022114
);
21032115
}

crates/emmylua_formatter/src/test/expression_tests.rs

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ mod tests {
33
// ========== unary / binary / concat ==========
44

55
use crate::{
6-
assert_format, assert_format_with_config,
6+
SourceText, assert_format, assert_format_with_config,
77
config::{LayoutConfig, LuaFormatConfig},
8+
reformat_lua_code,
89
};
10+
use emmylua_parser::LuaLanguageLevel;
911

1012
#[test]
1113
fn test_unary_expr() {
@@ -763,6 +765,120 @@ end)
763765
);
764766
}
765767

768+
#[test]
769+
fn test_chained_call_suffix_does_not_double_indent_multiline_args() {
770+
assert_format!(
771+
r#"a.a = function()
772+
return function(l)
773+
a.Add(
774+
aaaa,
775+
bbbb,
776+
cccc,
777+
dddd,
778+
eeee,
779+
nil,
780+
nil,
781+
nil,
782+
aafafa -- comment
783+
)()
784+
end
785+
end
786+
"#,
787+
r#"a.a = function()
788+
return function(l)
789+
a.Add(
790+
aaaa,
791+
bbbb,
792+
cccc,
793+
dddd,
794+
eeee,
795+
nil,
796+
nil,
797+
nil,
798+
aafafa -- comment
799+
)()
800+
end
801+
end
802+
"#
803+
);
804+
}
805+
806+
#[test]
807+
fn test_chained_index_after_multiline_call_does_not_double_indent_args() {
808+
assert_format!(
809+
r#"a.a = function()
810+
return function(l)
811+
return a.Add(
812+
aaaa,
813+
bbbb,
814+
cccc,
815+
dddd,
816+
eeee,
817+
nil,
818+
nil,
819+
nil,
820+
aafafa -- comment
821+
)[1]
822+
end
823+
end
824+
"#,
825+
r#"a.a = function()
826+
return function(l)
827+
return a.Add(
828+
aaaa,
829+
bbbb,
830+
cccc,
831+
dddd,
832+
eeee,
833+
nil,
834+
nil,
835+
nil,
836+
aafafa -- comment
837+
)[1]
838+
end
839+
end
840+
"#
841+
);
842+
}
843+
844+
#[test]
845+
fn test_chained_method_after_multiline_call_does_not_double_indent_args() {
846+
assert_format!(
847+
r#"a.a = function()
848+
return function(l)
849+
return a.Add(
850+
aaaa,
851+
bbbb,
852+
cccc,
853+
dddd,
854+
eeee,
855+
nil,
856+
nil,
857+
nil,
858+
aafafa -- comment
859+
):next()
860+
end
861+
end
862+
"#,
863+
r#"a.a = function()
864+
return function(l)
865+
return a.Add(
866+
aaaa,
867+
bbbb,
868+
cccc,
869+
dddd,
870+
eeee,
871+
nil,
872+
nil,
873+
nil,
874+
aafafa -- comment
875+
):next()
876+
end
877+
end
878+
"#
879+
);
880+
}
881+
766882
#[test]
767883
fn test_multiline_call_comparison_keeps_short_rhs_on_closing_line() {
768884
let config = LuaFormatConfig {
@@ -787,6 +903,41 @@ end, 'LOADTRUE', 'RETURN1') == "hiho")
787903
);
788904
}
789905

906+
#[test]
907+
fn test_user_multiline_assert_comparison_keeps_eq_on_call_closing_line() {
908+
let input = r#"assert(
909+
T.checkpanic(
910+
[[
911+
pushstring "return {__close = function () Y = 'ho'; end}"
912+
newtable
913+
loadstring -2
914+
call 0 1
915+
setmetatable -2
916+
toclose -1
917+
pushstring "hi"
918+
error
919+
]], [[
920+
getglobal Y
921+
concat 2 # concat original error with global Y
922+
]]
923+
)
924+
== "hiho"
925+
)
926+
"#;
927+
let result = reformat_lua_code(
928+
&SourceText {
929+
text: input,
930+
level: LuaLanguageLevel::default(),
931+
},
932+
&LuaFormatConfig::default(),
933+
);
934+
935+
assert!(
936+
result.contains(") == \"hiho\"") || result.contains(") == \"hiho\""),
937+
"expected comparison tail to stay on the call closing line, got:\n{result}"
938+
);
939+
}
940+
790941
#[test]
791942
fn test_table_auto_without_alignment_uses_progressive_fill() {
792943
let config = LuaFormatConfig {

0 commit comments

Comments
 (0)