Conversation
Reasoning DetailsWe are asked to review the code changes in a pull request diff. The diff introduces a new module `range_format` in the formatter, adds public functions `reformat_range` and `reformat_range_in_chunk` to the library crate, modifies the document formatting handler to extract a shared config builder, and rewrites the range formatting handler to use the new range formatter instead of the old approach of formatting the whole document and filtering edits.We need to analyze for potential issues: code style, logical errors, security vulnerabilities, performance, correctness, etc. Provide a concise list of problems and recommendations. Let's go through the diff file by file.
Potential issues:
Potential issues:
Potential logical issues:
Potential missing edge cases:
Now, list issues and recommendations in a concise manner. Issues:
Minor style issues: None that stand out. Recommendations:
No security vulnerabilities identified. Recommendation: The changes are well-structured and appear correct. The new range formatting approach is cleaner and more efficient by avoiding formatting the entire document. The main potential improvement is the fallback behavior if explicit target formatting fails. Code Review SummaryThe PR introduces a new range formatting module for the EmmyLua formatter, replacing the previous approach of formatting the entire document and filtering edits. The changes are well-structured and improve efficiency, but a few areas deserve attention. Potential Issues
Positive Highlights
Minor Observations
No security vulnerabilities were identified. The changes are a solid improvement to the formatter’s capabilities. |
There was a problem hiding this comment.
Code Review
This pull request introduces a dedicated range formatting implementation for Lua. It adds the range_format module to emmylua_formatter, which supports formatting specific AST nodes like tables and parameter lists by wrapping them in a temporary context, as well as formatting arbitrary selections by expanding them to full lines. The emmylua_ls range formatting handler is refactored to utilize this new logic, replacing the previous diff-based approach. Review feedback highlights an opportunity to optimize node lookups using covering_element and identifies a potential indentation issue when formatting multi-line sub-expressions that are not at the start of a line.
| if let Some(target) = select_explicit_format_target(chunk, selection) { | ||
| return format_explicit_target(source_text, target, level, config); | ||
| } |
There was a problem hiding this comment.
When formatting an explicit target (like a TableExpr or ParamList) that spans multiple lines, the resulting text may have incorrect indentation if the target is not at the start of the line. The base indentation of the line where the target starts should be calculated and applied to all subsequent lines of the formatted output to maintain correct alignment.
| if let Some(target) = select_explicit_format_target(chunk, selection) { | |
| return format_explicit_target(source_text, target, level, config); | |
| } | |
| if let Some(target) = select_explicit_format_target(chunk, selection) { | |
| let line_start = line_start_offset(source_text, usize::from(target.replace_range.start())); | |
| let indent_prefix = line_indent_prefix(source_text, TextSize::new(line_start as u32)); | |
| return format_explicit_target(source_text, target, level, config, &indent_prefix); | |
| } |
| fn format_explicit_target( | ||
| source_text: &str, | ||
| target: ExplicitFormatTarget, | ||
| level: LuaLanguageLevel, | ||
| config: &LuaFormatConfig, | ||
| ) -> Option<RangeFormatOutput> { | ||
| let fragment = &source_text | ||
| [usize::from(target.replace_range.start())..usize::from(target.replace_range.end())]; | ||
| if fragment.trim().is_empty() { | ||
| return None; | ||
| } | ||
|
|
||
| let wrapped_fragment = wrap_explicit_fragment(target.kind, fragment); | ||
| let formatted_wrapper = format_fragment(&wrapped_fragment, level, config)?; | ||
| let extracted = extract_explicit_fragment(&formatted_wrapper, target.kind, level)?; | ||
|
|
||
| Some(RangeFormatOutput { | ||
| replace_range: target.replace_range, | ||
| text: extracted, | ||
| }) | ||
| } |
There was a problem hiding this comment.
Update format_explicit_target to accept an indent_prefix and apply it to all lines of the formatted output except the first one. This ensures that multi-line sub-expressions are correctly indented relative to their starting line in the original source.
fn format_explicit_target(
source_text: &str,
target: ExplicitFormatTarget,
level: LuaLanguageLevel,
config: &LuaFormatConfig,
indent_prefix: &str,
) -> Option<RangeFormatOutput> {
let fragment = &source_text
[usize::from(target.replace_range.start())..usize::from(target.replace_range.end())];
if fragment.trim().is_empty() {
return None;
}
let wrapped_fragment = wrap_explicit_fragment(target.kind, fragment);
let formatted_wrapper = format_fragment(&wrapped_fragment, level, config)?;
let extracted = extract_explicit_fragment(&formatted_wrapper, target.kind, level)?;
let mut text = String::new();
for (i, line) in extracted.split_inclusive('\n').enumerate() {
let (content, newline) = split_line_ending(line);
if i > 0 && !content.is_empty() {
text.push_str(indent_prefix);
}
text.push_str(content);
text.push_str(newline);
}
Some(RangeFormatOutput {
replace_range: target.replace_range,
text,
})
}| fn find_smallest_containing<N: LuaAstNode>( | ||
| root: &LuaSyntaxNode, | ||
| selection: TextRange, | ||
| ) -> Option<N> { | ||
| root.descendants() | ||
| .filter_map(N::cast) | ||
| .filter(|node| contains_range(node.get_range(), selection)) | ||
| .min_by_key(|node| text_range_len(node.get_range())) | ||
| } |
There was a problem hiding this comment.
The current implementation of find_smallest_containing is inefficient for large files as it iterates over all descendants of the root node ($O(N)$). Since you have the selection range, you can use covering_element to jump directly to the smallest element containing the range and then traverse upwards through its ancestors ($O(\text{depth})$).
fn find_smallest_containing<N: LuaAstNode>(
root: &LuaSyntaxNode,
selection: TextRange,
) -> Option<N> {
root.covering_element(selection)
.ancestors()
.find_map(N::cast)
}|
/review |
1 similar comment
|
/review |
|
/review |
|
/review |
1 similar comment
|
/review |
Code Review SummaryThis PR introduces range formatting support for the EmmyLua formatter. Here are the key findings: ✅ Positive Aspects
|
test deepseek