From d311d3bc5b9b9af7d3264ac412f1b78d747fd6a9 Mon Sep 17 00:00:00 2001 From: dean-starkware Date: Thu, 19 Sep 2024 15:31:14 +0300 Subject: [PATCH] add closing parenthesis to methods completion (#6380) --- .../src/formatter_impl.rs | 216 +++++++++++++++++- .../src/node_properties.rs | 4 + crates/cairo-lang-formatter/src/test.rs | 5 + .../cairo_files/sorted_mod_use.cairo | 17 ++ .../expected_results/sorted_mod_use.cairo | 16 ++ .../src/ide/completion/completions.rs | 3 +- .../tests/e2e/completions.rs | 3 + .../completions/methods_text_edits.txt | 54 +++++ .../diagnostics/expr_diagnostics | 4 + .../src/parser_test_data/partial_trees/use | 51 ++++- scripts/cairo_fmt.sh | 2 +- 11 files changed, 366 insertions(+), 9 deletions(-) create mode 100644 crates/cairo-lang-formatter/test_data/cairo_files/sorted_mod_use.cairo create mode 100644 crates/cairo-lang-formatter/test_data/expected_results/sorted_mod_use.cairo diff --git a/crates/cairo-lang-formatter/src/formatter_impl.rs b/crates/cairo-lang-formatter/src/formatter_impl.rs index 07baccea800..bf9cef3be28 100644 --- a/crates/cairo-lang-formatter/src/formatter_impl.rs +++ b/crates/cairo-lang-formatter/src/formatter_impl.rs @@ -4,6 +4,11 @@ use std::fmt; use cairo_lang_filesystem::span::TextWidth; use cairo_lang_syntax as syntax; use cairo_lang_syntax::attribute::consts::FMT_SKIP_ATTR; +use cairo_lang_syntax::node::ast::{ + ItemUse, TerminalLBrace, TerminalRBrace, UsePath, UsePathGreen, UsePathLeaf, UsePathLeafGreen, + UsePathList, UsePathListElementOrSeparatorGreen, UsePathMulti, UsePathMultiGreen, + UsePathSingle, UsePathSingleGreen, +}; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::{ast, SyntaxNode, Terminal, TypedSyntaxNode}; use itertools::Itertools; @@ -758,6 +763,8 @@ pub trait SyntaxNodeFormat { /// Otherwise, returns None. fn get_protected_zone_precedence(&self, db: &dyn SyntaxGroup) -> Option; fn should_skip_terminal(&self, db: &dyn SyntaxGroup) -> bool; + /// Should a sequence of syntax nodes of this kind be sorted. + fn should_sort(&self, db: &dyn SyntaxGroup) -> Option; } pub struct FormatterImpl<'a> { @@ -817,15 +824,217 @@ impl<'a> FormatterImpl<'a> { } self.append_break_line_point(node_break_points.trailing()); } + + fn sort_inner_use_paths_in_place(multi_path: &ast::UsePathMulti, db: &dyn SyntaxGroup) { + // Step 1: Extract all inner paths + let mut paths = multi_path.use_paths(db).elements(db).into_iter().collect::>(); + + // Step 2: Sort the paths based on their text representation + paths.sort_by_key(|path| match path { + ast::UsePath::Leaf(leaf) => { + let ident = leaf.ident(db); // Get the identifier + ident.as_syntax_node().get_text_without_trivia(db) // Get the text without trivia + } + ast::UsePath::Single(single) => { + let ident = single.ident(db); // Get the identifier + ident.as_syntax_node().get_text_without_trivia(db) // Get the text without trivia + } + ast::UsePath::Multi(multi) => multi.as_syntax_node().get_text_without_trivia(db), + }); + + // Step 3: Output the sorted paths in the desired format + for path in paths { + match path { + ast::UsePath::Leaf(leaf) => { + let ident = leaf.ident(db); + println!("Leaf: {}", ident.as_syntax_node().get_text_without_trivia(db)); + } + ast::UsePath::Single(single) => { + let ident = single.ident(db); + println!("Single: {}", ident.as_syntax_node().get_text_without_trivia(db)); + } + ast::UsePath::Multi(multi) => { + println!("Multi: {}", multi.as_syntax_node().get_text_without_trivia(db)); + } + } + } + } + + fn sort_and_append_group<'b>( + group: &mut Vec<&'b SyntaxNode>, // Both group and sorted_children now share lifetime 'b + kind: SyntaxKind, + sorted_children: &mut Vec<&'b SyntaxNode>, + db: &dyn SyntaxGroup, + ) { + if group.is_empty() { + return; + } + + match kind { + SyntaxKind::ItemModule => { + group.sort_by_key(|c| { + let item_module = ast::ItemModule::from_syntax_node(db, (*c).clone()); + item_module.name(db).text(db) + }); + } + SyntaxKind::ItemUse => { + group.sort_by_key(|c| { + let item_use = ast::ItemUse::from_syntax_node(db, (*c).clone()); + let use_path = item_use.use_path(db); + + // Sort by the path's identifier or full path text + match use_path { + UsePath::Leaf(leaf) => { + leaf.ident(db).as_syntax_node().get_text_without_trivia(db) + } + UsePath::Single(single) => { + single.ident(db).as_syntax_node().get_text_without_trivia(db) + } + ast::UsePath::Multi(multi) => { + // Call the sort_inner_use_paths_in_place to sort the inner paths + Self::sort_inner_use_paths_in_place(&multi, db); + multi.as_syntax_node().get_text_without_trivia(db) + } + } + }); + } + _ => {} + } + sorted_children.append(group); + } + /// Formats an internal node and appends the formatted string to the result. fn format_internal(&mut self, syntax_node: &SyntaxNode) { let allowed_empty_between = syntax_node.allowed_empty_between(self.db); let internal_break_line_points_positions = syntax_node.get_internal_break_line_point_properties(self.db); // TODO(ilya): consider not copying here. + let allowed_empty_between = syntax_node.allowed_empty_between(self.db); + let internal_break_line_points_positions = + syntax_node.get_internal_break_line_point_properties(self.db); let mut children = self.db.get_children(syntax_node.clone()).to_vec(); let n_children = children.len(); if self.config.sort_module_level_items { + let mut sorted_children = Vec::new(); + let mut current_mod_group = Vec::new(); + let mut current_use_group = Vec::new(); + let mut current_use_path_group = Vec::new(); + // Iterate through the children and handle sorting: + for child in children.iter() { + match child.kind(self.db) { + SyntaxKind::ItemModule => { + if !current_use_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_group, + SyntaxKind::ItemUse, + &mut sorted_children, + self.db, + ); + } + if !current_use_path_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_path_group, + SyntaxKind::UsePathMulti, + &mut sorted_children, + self.db, + ); + } + current_mod_group.push(child); + } + SyntaxKind::ItemUse => { + if !current_mod_group.is_empty() { + Self::sort_and_append_group( + &mut current_mod_group, + SyntaxKind::ItemModule, + &mut sorted_children, + self.db, + ); + } + if !current_use_path_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_path_group, + SyntaxKind::UsePathMulti, + &mut sorted_children, + self.db, + ); + } + current_use_group.push(child); + } + SyntaxKind::UsePathMulti => { + if !current_mod_group.is_empty() { + Self::sort_and_append_group( + &mut current_mod_group, + SyntaxKind::ItemModule, + &mut sorted_children, + self.db, + ); + } + if !current_use_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_group, + SyntaxKind::ItemUse, + &mut sorted_children, + self.db, + ); + } + current_use_path_group.push(child); + } + _ => { + if !current_mod_group.is_empty() { + Self::sort_and_append_group( + &mut current_mod_group, + SyntaxKind::ItemModule, + &mut sorted_children, + self.db, + ); + } + if !current_use_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_group, + SyntaxKind::ItemUse, + &mut sorted_children, + self.db, + ); + } + if !current_use_path_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_path_group, + SyntaxKind::UsePathMulti, + &mut sorted_children, + self.db, + ); + } + sorted_children.push(child); + } + } + } + // Append any remaining groups: + if !current_mod_group.is_empty() { + Self::sort_and_append_group( + &mut current_mod_group, + SyntaxKind::ItemModule, + &mut sorted_children, + self.db, + ); + } + if !current_use_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_group, + SyntaxKind::ItemUse, + &mut sorted_children, + self.db, + ); + } + if !current_use_path_group.is_empty() { + Self::sort_and_append_group( + &mut current_use_path_group, + SyntaxKind::UsePathMulti, + &mut sorted_children, + self.db, + ); + } + // Replace the children with the sorted result: + // children = sorted_children.into_iter().cloned().collect(); children.sort_by_key(|c| MovableNode::new(self.db, c)); }; for (i, child) in children.iter().enumerate() { @@ -843,6 +1052,7 @@ impl<'a> FormatterImpl<'a> { self.empty_lines_allowance = allowed_empty_between; } } + /// Formats a terminal node and appends the formatted string to the result. fn format_terminal(&mut self, syntax_node: &SyntaxNode) { // TODO(spapini): Introduce a Terminal and a Token enum in ast.rs to make this cleaner. @@ -921,7 +1131,6 @@ impl<'a> FormatterImpl<'a> { syntax_node.has_attr(self.db, FMT_SKIP_ATTR) } } - /// Represents a sortable SyntaxNode. #[derive(PartialEq, Eq)] enum MovableNode { @@ -941,6 +1150,11 @@ impl MovableNode { Self::Immovable } } + // TODO(Dean): Fix this to ignore attributes. kind- if we need to sort. than have + // sequence to know if to sort and then by the module name. mode...something..{} + // mod haws and use doesnt. mod is more עדין because only on not body type. + // cairo_specs- 491 and 670- item module and etc. the other one- no name so by use path. + // every sequence- =diifrenet function to decide by which to sort. SyntaxKind::ItemUse => Self::ItemUse(node.clone().get_text_without_trivia(db).into()), SyntaxKind::ItemHeaderDoc => Self::ItemHeaderDoc, _ => Self::Immovable, diff --git a/crates/cairo-lang-formatter/src/node_properties.rs b/crates/cairo-lang-formatter/src/node_properties.rs index ba682973b9c..e2034b2d3f2 100644 --- a/crates/cairo-lang-formatter/src/node_properties.rs +++ b/crates/cairo-lang-formatter/src/node_properties.rs @@ -720,6 +720,10 @@ impl SyntaxNodeFormat for SyntaxNode { false } } + + fn should_sort(&self, db: &dyn SyntaxGroup) -> Option { + todo!() + } } /// For statement lists, returns if we want these as a single line. diff --git a/crates/cairo-lang-formatter/src/test.rs b/crates/cairo-lang-formatter/src/test.rs index b8f598dc3f9..c0665b6caf7 100644 --- a/crates/cairo-lang-formatter/src/test.rs +++ b/crates/cairo-lang-formatter/src/test.rs @@ -41,6 +41,11 @@ impl Upcast for DatabaseImpl { "test_data/expected_results/fmt_skip.cairo", false )] +#[test_case( + "test_data/cairo_files/sorted_mod_use.cairo", + "test_data/expected_results/sorted_mod_use.cairo", + false +)] fn format_and_compare_file(unformatted_filename: &str, expected_filename: &str, use_sorting: bool) { let db_val = SimpleParserDatabase::default(); let db = &db_val; diff --git a/crates/cairo-lang-formatter/test_data/cairo_files/sorted_mod_use.cairo b/crates/cairo-lang-formatter/test_data/cairo_files/sorted_mod_use.cairo new file mode 100644 index 00000000000..253bb7dc105 --- /dev/null +++ b/crates/cairo-lang-formatter/test_data/cairo_files/sorted_mod_use.cairo @@ -0,0 +1,17 @@ +mod zeta; +mod alpha; +mod gamma; + +use std::fs; +use std::io::Write; +use std::path::PathBuf; +use std::collections::HashMap; +use std::env; + +mod beta; +use crate::utils::{a, b, d, c}; + +fn main() { + // Example function + println!("Hello, world!"); +} diff --git a/crates/cairo-lang-formatter/test_data/expected_results/sorted_mod_use.cairo b/crates/cairo-lang-formatter/test_data/expected_results/sorted_mod_use.cairo new file mode 100644 index 00000000000..b1e451393ef --- /dev/null +++ b/crates/cairo-lang-formatter/test_data/expected_results/sorted_mod_use.cairo @@ -0,0 +1,16 @@ +mod alpha; +mod beta; +mod gamma; +mod zeta; + +use crate::utils::{a, b, c, d}; +use std::collections::HashMap; +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Example function + println!("Hello, world!"); +} diff --git a/crates/cairo-lang-language-server/src/ide/completion/completions.rs b/crates/cairo-lang-language-server/src/ide/completion/completions.rs index 452a3190bc8..f0ad3d21eee 100644 --- a/crates/cairo-lang-language-server/src/ide/completion/completions.rs +++ b/crates/cairo-lang-language-server/src/ide/completion/completions.rs @@ -281,7 +281,8 @@ pub fn completion_for_method( let completion = CompletionItem { label: format!("{}()", name), - insert_text: Some(format!("{}(", name)), + insert_text: Some(format!("{}($0)", name)), + insert_text_format: Some(tower_lsp::lsp_types::InsertTextFormat::SNIPPET), detail: Some(detail), kind: Some(CompletionItemKind::METHOD), additional_text_edits: Some(additional_text_edits), diff --git a/crates/cairo-lang-language-server/tests/e2e/completions.rs b/crates/cairo-lang-language-server/tests/e2e/completions.rs index 840e94eac45..e8901e84703 100644 --- a/crates/cairo-lang-language-server/tests/e2e/completions.rs +++ b/crates/cairo-lang-language-server/tests/e2e/completions.rs @@ -63,6 +63,9 @@ fn test_completions_text_edits( if let Some(text_edit) = completion.additional_text_edits { report.push_str("--------------------------\n"); report.push_str(format!("Completion: {}\n", completion.label).as_str()); + if let Some(text) = completion.insert_text { + report.push_str(format!("Insert text: {text}\n").as_str()); + } for edit in text_edit { report.push_str(format!("Text edit: {}", edit.new_text).as_str()); } diff --git a/crates/cairo-lang-language-server/tests/test_data/completions/methods_text_edits.txt b/crates/cairo-lang-language-server/tests/test_data/completions/methods_text_edits.txt index b950f2bcd45..799334c3c00 100644 --- a/crates/cairo-lang-language-server/tests/test_data/completions/methods_text_edits.txt +++ b/crates/cairo-lang-language-server/tests/test_data/completions/methods_text_edits.txt @@ -33,74 +33,101 @@ mod inner_mod { x.some_me -------------------------- Completion: add_eq() +Insert text: add_eq($0) Text edit: use core::traits::AddEq; -------------------------- Completion: sub_eq() +Insert text: sub_eq($0) Text edit: use core::traits::SubEq; -------------------------- Completion: mul_eq() +Insert text: mul_eq($0) Text edit: use core::traits::MulEq; -------------------------- Completion: into() +Insert text: into($0) -------------------------- Completion: try_into() +Insert text: try_into($0) -------------------------- Completion: destruct() +Insert text: destruct($0) -------------------------- Completion: panic_destruct() +Insert text: panic_destruct($0) -------------------------- Completion: new_inputs() +Insert text: new_inputs($0) Text edit: use core::circuit::CircuitInputs; -------------------------- Completion: get_descriptor() +Insert text: get_descriptor($0) -------------------------- Completion: clone() +Insert text: clone($0) -------------------------- Completion: is_zero() +Insert text: is_zero($0) Text edit: use core::num::traits::Zero; -------------------------- Completion: is_non_zero() +Insert text: is_non_zero($0) Text edit: use core::num::traits::Zero; -------------------------- Completion: is_one() +Insert text: is_one($0) Text edit: use core::num::traits::One; -------------------------- Completion: is_non_one() +Insert text: is_non_one($0) Text edit: use core::num::traits::One; -------------------------- Completion: add_assign() +Insert text: add_assign($0) Text edit: use core::ops::AddAssign; -------------------------- Completion: sub_assign() +Insert text: sub_assign($0) Text edit: use core::ops::SubAssign; -------------------------- Completion: mul_assign() +Insert text: mul_assign($0) Text edit: use core::ops::MulAssign; -------------------------- Completion: serialize() +Insert text: serialize($0) -------------------------- Completion: print() +Insert text: print($0) -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::Display; -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::Debug; -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::LowerHex; -------------------------- Completion: is_zero() +Insert text: is_zero($0) -------------------------- Completion: is_non_zero() +Insert text: is_non_zero($0) -------------------------- Completion: append_formatted_to_byte_array() +Insert text: append_formatted_to_byte_array($0) Text edit: use core::to_byte_array::AppendFormattedToByteArray; -------------------------- Completion: format_as_byte_array() +Insert text: format_as_byte_array($0) Text edit: use core::to_byte_array::FormatAsByteArray; -------------------------- Completion: some_method() +Insert text: some_method($0) Text edit: use super::ATrait1; //! > ========================================================================== @@ -141,72 +168,99 @@ mod inner_mod { x.some_me -------------------------- Completion: add_eq() +Insert text: add_eq($0) Text edit: use core::traits::AddEq; -------------------------- Completion: sub_eq() +Insert text: sub_eq($0) Text edit: use core::traits::SubEq; -------------------------- Completion: mul_eq() +Insert text: mul_eq($0) Text edit: use core::traits::MulEq; -------------------------- Completion: into() +Insert text: into($0) -------------------------- Completion: try_into() +Insert text: try_into($0) -------------------------- Completion: destruct() +Insert text: destruct($0) -------------------------- Completion: panic_destruct() +Insert text: panic_destruct($0) -------------------------- Completion: new_inputs() +Insert text: new_inputs($0) Text edit: use core::circuit::CircuitInputs; -------------------------- Completion: get_descriptor() +Insert text: get_descriptor($0) -------------------------- Completion: clone() +Insert text: clone($0) -------------------------- Completion: is_zero() +Insert text: is_zero($0) Text edit: use core::num::traits::Zero; -------------------------- Completion: is_non_zero() +Insert text: is_non_zero($0) Text edit: use core::num::traits::Zero; -------------------------- Completion: is_one() +Insert text: is_one($0) Text edit: use core::num::traits::One; -------------------------- Completion: is_non_one() +Insert text: is_non_one($0) Text edit: use core::num::traits::One; -------------------------- Completion: add_assign() +Insert text: add_assign($0) Text edit: use core::ops::AddAssign; -------------------------- Completion: sub_assign() +Insert text: sub_assign($0) Text edit: use core::ops::SubAssign; -------------------------- Completion: mul_assign() +Insert text: mul_assign($0) Text edit: use core::ops::MulAssign; -------------------------- Completion: serialize() +Insert text: serialize($0) -------------------------- Completion: print() +Insert text: print($0) -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::Display; -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::Debug; -------------------------- Completion: fmt() +Insert text: fmt($0) Text edit: use core::fmt::LowerHex; -------------------------- Completion: is_zero() +Insert text: is_zero($0) -------------------------- Completion: is_non_zero() +Insert text: is_non_zero($0) -------------------------- Completion: append_formatted_to_byte_array() +Insert text: append_formatted_to_byte_array($0) Text edit: use core::to_byte_array::AppendFormattedToByteArray; -------------------------- Completion: format_as_byte_array() +Insert text: format_as_byte_array($0) Text edit: use core::to_byte_array::FormatAsByteArray; -------------------------- Completion: some_method() +Insert text: some_method($0) Text edit: use super::ATrait1; diff --git a/crates/cairo-lang-parser/src/parser_test_data/diagnostics/expr_diagnostics b/crates/cairo-lang-parser/src/parser_test_data/diagnostics/expr_diagnostics index 656cd43eadd..c3f3e74560a 100644 --- a/crates/cairo-lang-parser/src/parser_test_data/diagnostics/expr_diagnostics +++ b/crates/cairo-lang-parser/src/parser_test_data/diagnostics/expr_diagnostics @@ -22,6 +22,10 @@ error: Missing tokens. Expected an expression. get_diagnostics //! > cairo_code +use A; +use C; +use B; + fn f() { { 5 diff --git a/crates/cairo-lang-parser/src/parser_test_data/partial_trees/use b/crates/cairo-lang-parser/src/parser_test_data/partial_trees/use index a50854a6987..6028e60f08c 100644 --- a/crates/cairo-lang-parser/src/parser_test_data/partial_trees/use +++ b/crates/cairo-lang-parser/src/parser_test_data/partial_trees/use @@ -5,7 +5,7 @@ test_partial_parser_tree(expect_diagnostics: false) //! > cairo_code fn foo() { - use X::Y; + use A::{C, D::E::V, F::{G, H::I}}; } //! > top_level_kind @@ -22,12 +22,51 @@ ItemUse ├── use_kw (kind: TokenUse): 'use' ├── use_path (kind: UsePathSingle) │ ├── ident (kind: PathSegmentSimple) - │ │ └── ident (kind: TokenIdentifier): 'X' + │ │ └── ident (kind: TokenIdentifier): 'A' │ ├── colon_colon (kind: TokenColonColon): '::' - │ └── use_path (kind: UsePathLeaf) - │ ├── ident (kind: PathSegmentSimple) - │ │ └── ident (kind: TokenIdentifier): 'Y' - │ └── alias_clause (kind: OptionAliasClauseEmpty) [] + │ └── use_path (kind: UsePathMulti) + │ ├── lbrace (kind: TokenLBrace): '{' + │ ├── use_paths (kind: UsePathList) + │ │ ├── item #0 (kind: UsePathLeaf) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'C' + │ │ │ └── alias_clause (kind: OptionAliasClauseEmpty) [] + │ │ ├── separator #0 (kind: TokenComma): ',' + │ │ ├── item #1 (kind: UsePathSingle) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'D' + │ │ │ ├── colon_colon (kind: TokenColonColon): '::' + │ │ │ └── use_path (kind: UsePathSingle) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'E' + │ │ │ ├── colon_colon (kind: TokenColonColon): '::' + │ │ │ └── use_path (kind: UsePathLeaf) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'V' + │ │ │ └── alias_clause (kind: OptionAliasClauseEmpty) [] + │ │ ├── separator #1 (kind: TokenComma): ',' + │ │ └── item #2 (kind: UsePathSingle) + │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ └── ident (kind: TokenIdentifier): 'F' + │ │ ├── colon_colon (kind: TokenColonColon): '::' + │ │ └── use_path (kind: UsePathMulti) + │ │ ├── lbrace (kind: TokenLBrace): '{' + │ │ ├── use_paths (kind: UsePathList) + │ │ │ ├── item #0 (kind: UsePathLeaf) + │ │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ │ └── ident (kind: TokenIdentifier): 'G' + │ │ │ │ └── alias_clause (kind: OptionAliasClauseEmpty) [] + │ │ │ ├── separator #0 (kind: TokenComma): ',' + │ │ │ └── item #1 (kind: UsePathSingle) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'H' + │ │ │ ├── colon_colon (kind: TokenColonColon): '::' + │ │ │ └── use_path (kind: UsePathLeaf) + │ │ │ ├── ident (kind: PathSegmentSimple) + │ │ │ │ └── ident (kind: TokenIdentifier): 'I' + │ │ │ └── alias_clause (kind: OptionAliasClauseEmpty) [] + │ │ └── rbrace (kind: TokenRBrace): '}' + │ └── rbrace (kind: TokenRBrace): '}' └── semicolon (kind: TokenSemicolon): ';' //! > ========================================================================== diff --git a/scripts/cairo_fmt.sh b/scripts/cairo_fmt.sh index f85393e38f3..06cc412fe00 100755 --- a/scripts/cairo_fmt.sh +++ b/scripts/cairo_fmt.sh @@ -1,3 +1,3 @@ #!/bin/bash -cargo run --profile=ci-dev --bin cairo-format -- --recursive "$@" +cargo run --profile=ci-dev --bin cairo-format -- -s --recursive "$@"