Skip to content

Commit f83492b

Browse files
authored
ide: code action to rewrite between != and <> (#1066)
not really necessary and something that the formatter will handle, but doing it because we can
1 parent d715a2e commit f83492b

2 files changed

Lines changed: 68 additions & 12 deletions

File tree

crates/squawk_ide/src/code_actions.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn code_actions(db: &dyn Db, file: File, offset: TextSize) -> Option<Vec<Cod
5353
rewrite_cast_to_double_colon(&mut actions, &source_file, offset);
5454
rewrite_double_colon_to_cast(&mut actions, &source_file, offset);
5555
rewrite_between_as_binary_expression(&mut actions, &source_file, offset);
56+
rewrite_not_equals_operator(&mut actions, &source_file, offset);
5657
rewrite_timestamp_type(&mut actions, &source_file, offset);
5758
Some(actions)
5859
}
@@ -682,6 +683,29 @@ fn rewrite_between_as_binary_expression(
682683
Some(())
683684
}
684685

686+
fn rewrite_not_equals_operator(
687+
actions: &mut Vec<CodeAction>,
688+
file: &ast::SourceFile,
689+
offset: TextSize,
690+
) -> Option<()> {
691+
let token = token_from_offset(file, offset)?;
692+
let bin_expr = token.parent_ancestors().find_map(ast::BinExpr::cast)?;
693+
694+
let (op_token, replacement, title) = match bin_expr.op()? {
695+
ast::BinOp::Neq(token) => (token, "<>", "Rewrite `!=` as `<>`"),
696+
ast::BinOp::Neqb(token) => (token, "!=", "Rewrite `<>` as `!=`"),
697+
_ => return None,
698+
};
699+
700+
actions.push(CodeAction {
701+
title: title.to_owned(),
702+
edits: vec![Edit::replace(op_token.text_range(), replacement.to_owned())],
703+
kind: ActionKind::RefactorRewrite,
704+
});
705+
706+
Some(())
707+
}
708+
685709
fn rewrite_timestamp_type(
686710
actions: &mut Vec<CodeAction>,
687711
file: &ast::SourceFile,
@@ -2003,6 +2027,38 @@ select myschema.f$0();"
20032027
));
20042028
}
20052029

2030+
#[test]
2031+
fn rewrite_not_equals_bang_to_angle() {
2032+
assert_snapshot!(
2033+
apply_code_action(rewrite_not_equals_operator, "select 1 !$0= 2;"),
2034+
@"select 1 <> 2;"
2035+
);
2036+
}
2037+
2038+
#[test]
2039+
fn rewrite_not_equals_angle_to_bang() {
2040+
assert_snapshot!(
2041+
apply_code_action(rewrite_not_equals_operator, "select 1 <$0> 2;"),
2042+
@"select 1 != 2;"
2043+
);
2044+
}
2045+
2046+
#[test]
2047+
fn rewrite_not_equals_cursor_on_operand() {
2048+
assert_snapshot!(
2049+
apply_code_action(rewrite_not_equals_operator, "select a$0 != b from t;"),
2050+
@"select a <> b from t;"
2051+
);
2052+
}
2053+
2054+
#[test]
2055+
fn rewrite_not_equals_not_applicable_other_op() {
2056+
assert!(code_action_not_applicable(
2057+
rewrite_not_equals_operator,
2058+
"select 1 =$0 2;"
2059+
));
2060+
}
2061+
20062062
#[test]
20072063
fn rewrite_values_as_select_simple() {
20082064
assert_snapshot!(

crates/squawk_syntax/src/ast/node_ext.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ pub enum BinOp {
8888
Caret(SyntaxToken),
8989
Collate(SyntaxToken),
9090
ColonColon(ast::ColonColon),
91-
ColonEq(ast::ColonEq),
91+
ColonEq(SyntaxToken),
9292
CustomOp(ast::CustomOp),
9393
Eq(SyntaxToken),
94-
FatArrow(ast::FatArrow),
95-
Gteq(ast::Gteq),
94+
FatArrow(SyntaxToken),
95+
Gteq(SyntaxToken),
9696
Ilike(SyntaxToken),
9797
In(SyntaxToken),
9898
Is(SyntaxToken),
@@ -101,10 +101,10 @@ pub enum BinOp {
101101
IsNotDistinctFrom(ast::IsNotDistinctFrom),
102102
LAngle(SyntaxToken),
103103
Like(SyntaxToken),
104-
Lteq(ast::Lteq),
104+
Lteq(SyntaxToken),
105105
Minus(SyntaxToken),
106-
Neq(ast::Neq),
107-
Neqb(ast::Neqb),
106+
Neq(SyntaxToken),
107+
Neqb(SyntaxToken),
108108
NotIlike(ast::NotIlike),
109109
NotIn(ast::NotIn),
110110
NotLike(ast::NotLike),
@@ -159,13 +159,19 @@ impl ast::BinExpr {
159159
SyntaxKind::AND_KW => BinOp::And(token),
160160
SyntaxKind::CARET => BinOp::Caret(token),
161161
SyntaxKind::COLLATE_KW => BinOp::Collate(token),
162+
SyntaxKind::COLON_EQ => BinOp::ColonEq(token),
162163
SyntaxKind::EQ => BinOp::Eq(token),
164+
SyntaxKind::FAT_ARROW => BinOp::FatArrow(token),
165+
SyntaxKind::GTEQ => BinOp::Gteq(token),
163166
SyntaxKind::ILIKE_KW => BinOp::Ilike(token),
164167
SyntaxKind::IN_KW => BinOp::In(token),
165168
SyntaxKind::IS_KW => BinOp::Is(token),
166169
SyntaxKind::L_ANGLE => BinOp::LAngle(token),
167170
SyntaxKind::LIKE_KW => BinOp::Like(token),
171+
SyntaxKind::LTEQ => BinOp::Lteq(token),
168172
SyntaxKind::MINUS => BinOp::Minus(token),
173+
SyntaxKind::NEQ => BinOp::Neq(token),
174+
SyntaxKind::NEQB => BinOp::Neqb(token),
169175
SyntaxKind::OR_KW => BinOp::Or(token),
170176
SyntaxKind::OVERLAPS_KW => BinOp::Overlaps(token),
171177
SyntaxKind::PERCENT => BinOp::Percent(token),
@@ -185,20 +191,14 @@ impl ast::BinExpr {
185191
SyntaxKind::COLON_COLON => {
186192
BinOp::ColonColon(ast::ColonColon { syntax: node })
187193
}
188-
SyntaxKind::COLON_EQ => BinOp::ColonEq(ast::ColonEq { syntax: node }),
189194
SyntaxKind::CUSTOM_OP => BinOp::CustomOp(ast::CustomOp { syntax: node }),
190-
SyntaxKind::FAT_ARROW => BinOp::FatArrow(ast::FatArrow { syntax: node }),
191-
SyntaxKind::GTEQ => BinOp::Gteq(ast::Gteq { syntax: node }),
192195
SyntaxKind::IS_DISTINCT_FROM => {
193196
BinOp::IsDistinctFrom(ast::IsDistinctFrom { syntax: node })
194197
}
195198
SyntaxKind::IS_NOT => BinOp::IsNot(ast::IsNot { syntax: node }),
196199
SyntaxKind::IS_NOT_DISTINCT_FROM => {
197200
BinOp::IsNotDistinctFrom(ast::IsNotDistinctFrom { syntax: node })
198201
}
199-
SyntaxKind::LTEQ => BinOp::Lteq(ast::Lteq { syntax: node }),
200-
SyntaxKind::NEQ => BinOp::Neq(ast::Neq { syntax: node }),
201-
SyntaxKind::NEQB => BinOp::Neqb(ast::Neqb { syntax: node }),
202202
SyntaxKind::NOT_ILIKE => BinOp::NotIlike(ast::NotIlike { syntax: node }),
203203
SyntaxKind::NOT_IN => BinOp::NotIn(ast::NotIn { syntax: node }),
204204
SyntaxKind::NOT_LIKE => BinOp::NotLike(ast::NotLike { syntax: node }),

0 commit comments

Comments
 (0)