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
2 changes: 1 addition & 1 deletion src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Formatter {
.set_language(&tree_sitter_gdscript::LANGUAGE.into())
.unwrap();
let tree = parser.parse(&content, None).unwrap();
let mut input_tree = GdTree::from_ts_tree(&tree, content.as_bytes());
let input_tree = GdTree::from_ts_tree(&tree, content.as_bytes());

Self {
content,
Expand Down
4 changes: 2 additions & 2 deletions src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl GDScriptLinter {
) -> Result<bool, Box<dyn std::error::Error>> {
let gdscript_files: Vec<&PathBuf> = input_files
.iter()
.filter(|path| path.extension().map_or(false, |ext| ext == "gd"))
.filter(|path| path.extension().is_some_and(|ext| ext == "gd"))
.collect();

if gdscript_files.is_empty() {
Expand Down Expand Up @@ -230,7 +230,7 @@ impl GDScriptLinter {
sorted_lines.sort();

for (i, &line_num) in sorted_lines.iter().enumerate() {
if let Some(line_issues) = line_issues.get(&line_num) {
if let Some(line_issues) = line_issues.get(line_num) {
println!(" {}:{}", file_path, line_num);
for issue in line_issues {
let (severity_str, severity_color) = match issue.severity {
Expand Down
4 changes: 2 additions & 2 deletions src/linter/rules/comparison_with_itself.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ impl Rule for ComparisonWithItselfRule {
let right_text = get_node_text(&right_node, source_code);

if left_text == right_text {
let (line, column) = get_line_column(&node);
let (line, column) = get_line_column(node);
issues.push(LintIssue::new(
line,
column,
"comparison-with-itself".to_string(),
LintSeverity::Warning,
format!(
"Redundant comparison '{}' - comparing expression with itself",
get_node_text(&node, source_code)
get_node_text(node, source_code)
),
));
}
Expand Down
14 changes: 7 additions & 7 deletions src/linter/rules/constant_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ impl ConstantNameRule {
}

fn is_preload_call(&self, node: &Node, source_code: &str) -> bool {
if node.kind() == "call" {
if let Some(function_node) = node.child(0) {
let function_name = get_node_text(&function_node, source_code);
return function_name == "preload";
}
if node.kind() == "call"
&& let Some(function_node) = node.child(0)
{
let function_name = get_node_text(&function_node, source_code);
return function_name == "preload";
}

false
Expand All @@ -50,7 +50,7 @@ impl Rule for ConstantNameRule {

if is_preload_const {
// For all load/preload constants, check load naming rules
if !self.is_valid_load_constant_name(&name) {
if !self.is_valid_load_constant_name(name) {
let (line, column) = get_line_column(&name_node);
issues.push(LintIssue::new(
line,
Expand All @@ -65,7 +65,7 @@ impl Rule for ConstantNameRule {
}
} else {
// For regular constants, just check regular rules
if !self.is_valid_constant_name(&name) {
if !self.is_valid_constant_name(name) {
let (line, column) = get_line_column(&name_node);
issues.push(LintIssue::new(
line,
Expand Down
34 changes: 17 additions & 17 deletions src/linter/rules/duplicated_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@ impl Rule for DuplicatedLoadRule {
fn check_node(&mut self, node: &Node, source_code: &str) -> Vec<LintIssue> {
if let Some(function_node) = node.child(0) {
let function_name = get_node_text(&function_node, source_code);
if function_name == "load" || function_name == "preload" {
if let Some(args_node) = node.child_by_field_name("arguments") {
let mut args_cursor = args_node.walk();
if args_cursor.goto_first_child() {
loop {
let arg_node = args_cursor.node();
if arg_node.kind() == "string" {
let path = get_node_text(&arg_node, source_code);
let (line, column) = get_line_column(&arg_node);
self.load_paths
.entry(path.to_string())
.or_insert_with(Vec::new)
.push((line, column));
}
if !args_cursor.goto_next_sibling() {
break;
}
if (function_name == "load" || function_name == "preload")
&& let Some(args_node) = node.child_by_field_name("arguments")
{
let mut args_cursor = args_node.walk();
if args_cursor.goto_first_child() {
loop {
let arg_node = args_cursor.node();
if arg_node.kind() == "string" {
let path = get_node_text(&arg_node, source_code);
let (line, column) = get_line_column(&arg_node);
self.load_paths
.entry(path.to_string())
.or_default()
.push((line, column));
}
if !args_cursor.goto_next_sibling() {
break;
}
}
}
Expand Down
37 changes: 18 additions & 19 deletions src/linter/rules/enum_member_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,24 @@ impl Rule for EnumMemberNameRule {
if enum_cursor.goto_first_child() {
loop {
let enum_member = enum_cursor.node();
if enum_member.kind() == "enumerator" {
if let Some(element_name_node) = enum_member.child_by_field_name("left") {
let element_name = get_node_text(&element_name_node, source_code);
// Skip empty enum member names (happens with empty enums)
if !element_name.is_empty()
&& !self.is_valid_enum_member_name(element_name)
{
let (line, column) = get_line_column(&element_name_node);
issues.push(LintIssue::new(
line,
column,
"enum-member-name".to_string(),
LintSeverity::Error,
format!(
"Enum element name '{}' should be in CONSTANT_CASE format",
element_name
),
));
}
if enum_member.kind() == "enumerator"
&& let Some(element_name_node) = enum_member.child_by_field_name("left")
{
let element_name = get_node_text(&element_name_node, source_code);
// Skip empty enum member names (happens with empty enums)
if !element_name.is_empty() && !self.is_valid_enum_member_name(element_name)
{
let (line, column) = get_line_column(&element_name_node);
issues.push(LintIssue::new(
line,
column,
"enum-member-name".to_string(),
LintSeverity::Error,
format!(
"Enum element name '{}' should be in CONSTANT_CASE format",
element_name
),
));
}
}
if !enum_cursor.goto_next_sibling() {
Expand Down
8 changes: 4 additions & 4 deletions src/linter/rules/no_else_return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ impl Rule for NoElseReturnRule {
));
}

if let Some(elif_body) = child_node.child_by_field_name("body") {
if !self.body_ends_with_return(&elif_body, source_code) {
all_branches_return = false;
}
if let Some(elif_body) = child_node.child_by_field_name("body")
&& !self.body_ends_with_return(&elif_body, source_code)
{
all_branches_return = false;
}
} else if child_node.kind() == "else_clause" {
let (line, column) = get_line_column(&child_node);
Expand Down
24 changes: 13 additions & 11 deletions src/linter/rules/standalone_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ impl Rule for StandaloneExpressionRule {

if let Some(expr_child) = node.child(0) {
let expr_kind = expr_child.kind();
if expr_kind != "call"
&& expr_kind != "assignment"
&& expr_kind != "augmented_assignment"
if expr_kind == "call"
|| expr_kind == "assignment"
|| expr_kind == "augmented_assignment"
{
if matches!(
expr_kind,
"binary_operator" | "integer" | "float" | "string" | "true" | "false" | "null"
) {
let (line, column) = get_line_column(&expr_child);
let expr_text = get_node_text(&expr_child, source_code);
issues.push(LintIssue::new(
return issues;
}

if matches!(
expr_kind,
"binary_operator" | "integer" | "float" | "string" | "true" | "false" | "null"
) {
let (line, column) = get_line_column(&expr_child);
let expr_text = get_node_text(&expr_child, source_code);
issues.push(LintIssue::new(
line,
column,
"standalone-expression".to_string(),
Expand All @@ -35,7 +38,6 @@ impl Rule for StandaloneExpressionRule {
expr_text
),
));
}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/linter/rules/variable_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ impl VariableNameRule {
}

fn is_load_call(&self, node: &Node, source_code: &str) -> bool {
if node.kind() == "call" {
if let Some(function_node) = node.child(0) {
let function_name = get_node_text(&function_node, source_code);
return function_name == "load" || function_name == "preload";
}
if node.kind() == "call"
&& let Some(function_node) = node.child(0)
{
let function_name = get_node_text(&function_node, source_code);
return function_name == "load" || function_name == "preload";
}
false
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let input_gdscript_files: Vec<&PathBuf> = args
.input
.iter()
.filter(|path| path.extension().map_or(false, |ext| ext == "gd"))
.filter(|path| path.extension().is_some_and(|ext| ext == "gd"))
.collect();

if input_gdscript_files.is_empty() {
Expand Down
5 changes: 3 additions & 2 deletions src/reorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn reorder_gdscript_elements(
tree: &Tree,
content: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let tokens = extract_tokens_to_reorder(&tree, content)?;
let tokens = extract_tokens_to_reorder(tree, content)?;
let ordered_elements = sort_gdscript_tokens(tokens);
let reordered_content = build_reordered_code(ordered_elements, content);

Expand Down Expand Up @@ -274,7 +274,7 @@ fn extract_tokens_to_reorder(
// annotations until we hit a declaration, at which point we attach the
// collected comments/annotations to that declaration.
for (node, text) in &all_nodes {
let reorderable_element = classify_element(*node, &text, content)?;
let reorderable_element = classify_element(*node, text, content)?;
classified_elements.push(ClassifiedElement {
node: *node,
text: text.clone(),
Expand Down Expand Up @@ -796,6 +796,7 @@ fn build_reordered_code(
};

if needs_spacing {
#[allow(clippy::if_same_then_else)]
Copy link
Copy Markdown
Contributor Author

@fstxz fstxz Oct 11, 2025

Choose a reason for hiding this comment

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

I silenced this warning, because if we collapse all 3 branches into one, the code becomes way less readable:

if is_function
    || (is_inner_class
        && matches!(
            previous_token_kind,
            Some(TokenKind::Method) | Some(TokenKind::InnerClass),
        ))
{
    output.push_str("\n\n");
} else {
    output.push('\n');
}

About this lint: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else

if is_function {
output.push_str("\n\n");
} else if is_inner_class && previous_token_kind == Some(TokenKind::Method) {
Expand Down