Skip to main content

tsz_solver/operations/
compound_assignment.rs

1use 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;