tsz_solver/operations/
compound_assignment.rs1use crate::{TypeDatabase, TypeId, type_queries};
2use tsz_scanner::SyntaxKind;
3
4pub const fn is_compound_assignment_operator(operator_token: u16) -> bool {
5 matches!(
6 operator_token,
7 k if k == SyntaxKind::PlusEqualsToken as u16
8 || k == SyntaxKind::MinusEqualsToken as u16
9 || k == SyntaxKind::AsteriskEqualsToken as u16
10 || k == SyntaxKind::AsteriskAsteriskEqualsToken as u16
11 || k == SyntaxKind::SlashEqualsToken as u16
12 || k == SyntaxKind::PercentEqualsToken as u16
13 || k == SyntaxKind::LessThanLessThanEqualsToken as u16
14 || k == SyntaxKind::GreaterThanGreaterThanEqualsToken as u16
15 || k == SyntaxKind::GreaterThanGreaterThanGreaterThanEqualsToken as u16
16 || k == SyntaxKind::AmpersandEqualsToken as u16
17 || k == SyntaxKind::BarEqualsToken as u16
18 || k == SyntaxKind::CaretEqualsToken as u16
19 || k == SyntaxKind::AmpersandAmpersandEqualsToken as u16
20 || k == SyntaxKind::BarBarEqualsToken as u16
21 || k == SyntaxKind::QuestionQuestionEqualsToken as u16
22 )
23}
24
25pub const fn map_compound_assignment_to_binary(operator_token: u16) -> Option<&'static str> {
26 match operator_token {
27 k if k == SyntaxKind::PlusEqualsToken as u16 => Some("+"),
28 k if k == SyntaxKind::MinusEqualsToken as u16 => Some("-"),
29 k if k == SyntaxKind::AsteriskEqualsToken as u16 => Some("*"),
30 k if k == SyntaxKind::AsteriskAsteriskEqualsToken as u16 => Some("**"),
31 k if k == SyntaxKind::SlashEqualsToken as u16 => Some("/"),
32 k if k == SyntaxKind::PercentEqualsToken as u16 => Some("%"),
33 k if k == SyntaxKind::LessThanLessThanEqualsToken as u16 => Some("<<"),
34 k if k == SyntaxKind::GreaterThanGreaterThanEqualsToken as u16 => Some(">>"),
35 k if k == SyntaxKind::GreaterThanGreaterThanGreaterThanEqualsToken as u16 => Some(">>>"),
36 k if k == SyntaxKind::AmpersandEqualsToken as u16 => Some("&"),
37 k if k == SyntaxKind::BarEqualsToken as u16 => Some("|"),
38 k if k == SyntaxKind::CaretEqualsToken as u16 => Some("^"),
39 k if k == SyntaxKind::AmpersandAmpersandEqualsToken as u16 => Some("&&"),
40 k if k == SyntaxKind::BarBarEqualsToken as u16 => Some("||"),
41 k if k == SyntaxKind::QuestionQuestionEqualsToken as u16 => Some("??"),
42 _ => None,
43 }
44}
45
46pub fn fallback_compound_assignment_result(
47 db: &dyn TypeDatabase,
48 operator_token: u16,
49 rhs_literal_type: Option<TypeId>,
50) -> Option<TypeId> {
51 match operator_token {
52 k if k == SyntaxKind::MinusEqualsToken as u16
53 || k == SyntaxKind::AsteriskEqualsToken as u16
54 || k == SyntaxKind::AsteriskAsteriskEqualsToken as u16
55 || k == SyntaxKind::SlashEqualsToken as u16
56 || k == SyntaxKind::PercentEqualsToken as u16
57 || k == SyntaxKind::LessThanLessThanEqualsToken as u16
58 || k == SyntaxKind::GreaterThanGreaterThanEqualsToken as u16
59 || k == SyntaxKind::GreaterThanGreaterThanGreaterThanEqualsToken as u16
60 || k == SyntaxKind::AmpersandEqualsToken as u16
61 || k == SyntaxKind::BarEqualsToken as u16
62 || k == SyntaxKind::CaretEqualsToken as u16 =>
63 {
64 Some(TypeId::NUMBER)
65 }
66 k if k == SyntaxKind::PlusEqualsToken as u16 => rhs_literal_type.and_then(|literal| {
67 if literal == TypeId::NUMBER || type_queries::is_number_literal(db, literal) {
68 Some(TypeId::NUMBER)
69 } else {
70 None
71 }
72 }),
73 _ => None,
74 }
75}
76
77#[cfg(test)]
78#[path = "../../tests/compound_assignment_tests.rs"]
79mod tests;