Skip to content

Commit

Permalink
test(core): properly test destructuring match
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLucqs committed Aug 8, 2024
1 parent e9a0f8b commit 27fc530
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 80 deletions.
6 changes: 3 additions & 3 deletions crates/cairo-lint-core/src/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn fix_semantic_diagnostic(db: &AnalysisDatabase, diag: &SemanticDiagnostic)
#[derive(Default)]
pub struct Fixer;
impl Fixer {
pub fn fix_if_let(&self, db: &dyn SyntaxGroup, node: SyntaxNode) -> String {
pub fn fix_destruct_match(&self, db: &dyn SyntaxGroup, node: SyntaxNode) -> String {
let match_expr = ExprMatch::from_syntax_node(db, node.clone());
let arms = match_expr.arms(db).elements(db);
let first_arm = &arms[0];
Expand All @@ -54,13 +54,13 @@ impl Fixer {
"{}if let {} = {} {{ {} }}",
node.get_text(db).chars().take_while(|c| c.is_whitespace()).collect::<String>(),
pattern,
match_expr.expr(db).as_syntax_node().get_text(db),
match_expr.expr(db).as_syntax_node().get_text_without_trivia(db),
first_expr.expression(db).as_syntax_node().get_text_without_trivia(db),
)
}
pub fn fix_plugin_diagnostic(&self, db: &AnalysisDatabase, diag: &PluginDiagnostic) -> String {
match diagnostic_kind_from_message(&diag.message) {
CairoLintKind::IfLet => self.fix_if_let(db, diag.stable_ptr.lookup(db.upcast())),
CairoLintKind::DestructMatch => self.fix_destruct_match(db, diag.stable_ptr.lookup(db.upcast())),
_ => "".to_owned(),
}
}
Expand Down
32 changes: 21 additions & 11 deletions crates/cairo-lint-core/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,31 @@ pub struct CairoLint;

#[derive(Debug, PartialEq)]
pub enum CairoLintKind {
IfLet,
If,
DestructMatch,
MatchForEquality,
Unknown,
}

pub fn diagnostic_kind_from_message(message: &str) -> CairoLintKind {
match message {
CairoLint::IF_LET => CairoLintKind::IfLet,
CairoLint::IF => CairoLintKind::If,
CairoLint::DESTRUCT_MATCH => CairoLintKind::DestructMatch,
CairoLint::MATCH_FOR_EQUALITY => CairoLintKind::MatchForEquality,
_ => CairoLintKind::Unknown,
}
}

impl CairoLint {
const IF_LET: &'static str =
const DESTRUCT_MATCH: &'static str =
"you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`";
const IF: &'static str = "you seem to be trying to use `match` for an equality check. Consider using `if`";
const MATCH_FOR_EQUALITY: &'static str =
"you seem to be trying to use `match` for an equality check. Consider using `if`";

pub fn check_match(&self, db: &dyn SyntaxGroup, match_expr: &ExprMatch, diagnostics: &mut Vec<PluginDiagnostic>) {
pub fn check_destruct_match(
&self,
db: &dyn SyntaxGroup,
match_expr: &ExprMatch,
diagnostics: &mut Vec<PluginDiagnostic>,
) {
let arms = match_expr.arms(db).deref().elements(db);
let mut is_single_armed = false;
let mut is_destructuring = false;
Expand All @@ -50,6 +56,9 @@ impl CairoLint {
let tuple_expr = match arm.expression(db) {
Expr::Block(block_expr) => {
let statements = block_expr.statements(db).elements(db);
if statements.is_empty() {
is_single_armed = true;
}
if statements.len() == 1 {
match &statements[0] {
Statement::Expr(statement_expr) => {
Expand All @@ -68,7 +77,8 @@ impl CairoLint {
Expr::Tuple(tuple_expr) => Some(tuple_expr),
_ => None,
};
is_single_armed = tuple_expr.is_some_and(|list| list.expressions(db).elements(db).is_empty());
is_single_armed = tuple_expr.is_some_and(|list| list.expressions(db).elements(db).is_empty())
|| is_single_armed;
}

Pattern::Enum(pat) => {
Expand All @@ -84,12 +94,12 @@ impl CairoLint {
match (is_single_armed, is_destructuring) {
(true, false) => diagnostics.push(PluginDiagnostic {
stable_ptr: match_expr.stable_ptr().untyped(),
message: Self::IF.to_string(),
message: Self::MATCH_FOR_EQUALITY.to_string(),
severity: Severity::Warning,
}),
(true, true) => diagnostics.push(PluginDiagnostic {
stable_ptr: match_expr.stable_ptr().untyped(),
message: Self::IF_LET.to_string(),
message: Self::DESTRUCT_MATCH.to_string(),
severity: Severity::Warning,
}),
(_, _) => (),
Expand All @@ -111,7 +121,7 @@ impl AnalyzerPlugin for CairoLint {
let descendants = func.as_syntax_node().descendants(db.upcast());
for descendant in descendants.into_iter() {
match descendant.kind(db.upcast()) {
SyntaxKind::ExprMatch => self.check_match(
SyntaxKind::ExprMatch => self.check_destruct_match(
db.upcast(),
&ExprMatch::from_syntax_node(db.upcast(), descendant),
&mut diags,
Expand Down
Loading

0 comments on commit 27fc530

Please sign in to comment.