Repository: astral-sh/ruff
File: crates/ty_ide/src/semantic_tokens.rs (Rust)

Code before:

    #[test]
    fn test_implicitly_concatenated_strings() {
        let test = SemanticTokenTest::new(
            r#"x = "hello" "world"
y = ("multi"
     "line"
     "string")
z = 'single' "mixed" 'quotes'"#,
        );

        let tokens = test.highlight_file();

        assert_snapshot!(test.to_snapshot(&tokens), @r#"
        "x" @ 0..1: Variable [definition]
        "\"hello\"" @ 4..11: String
        "\"world\"" @ 12..19: String
        "y" @ 20..21: Variable [definition]
        "\"multi\"" @ 25..32: String
        "\"line\"" @ 38..44: String
        "\"string\"" @ 50..58: String
        "z" @ 60..61: Variable [definition]
        "'single'" @ 64..72: String
        "\"mixed\"" @ 73..80: String
        "'quotes'" @ 81..89: String
        "#);
    }

    #[test]
    fn test_bytes_literals() {
        let test = SemanticTokenTest::new(
            r#"x = b"hello" b"world"
y = (b"multi"
     b"line"
     b"bytes")
z = b'single' b"mixed" b'quotes'"#,
        );

        let tokens = test.highlight_file();

        assert_snapshot!(test.to_snapshot(&tokens), @r#"
        "x" @ 0..1: Variable [definition]
        "b\"hello\"" @ 4..12: String
        "b\"world\"" @ 13..21: String
        "y" @ 22..23: Variable [definition]
        "b\"multi\"" @ 27..35: String
        "b\"line\"" @ 41..48: String
        "b\"bytes\"" @ 54..62: String
        "z" @ 64..65: Variable [definition]
        "b'single'" @ 68..77: String
        "b\"mixed\"" @ 78..86: String

Review comment (suggestion):
...we classify these as readonly? That feels like a pyrightism that crept into the code somewhere. We might want to reconsider that 🤔

Pyright implements a heuristic where SCREAMING_SNAKE_CASE constants are always treated as implicitly read-only. But in terms of the semantics _we_ give variables, we currently only treat variables as read-only if they are explicitly annotated as `Final` (as per the spec).

If this classification only affects the way these variables are syntax-highlighted by the editor, though, then maybe it's fine

Code after:
        "###);
    }

    #[test]
    fn test_constant_variations() {
        let test = SemanticTokenTest::new(
            r#"
A = 1
AB = 1
ABC = 1
A1 = 1
AB1 = 1
ABC1 = 1
A_B = 1
A1_B = 1
A_B1 = 1
A_1 = 1
"#,
        );

        let tokens = test.highlight_file();

        assert_snapshot!(test.to_snapshot(&tokens), @r#"
        "A" @ 1..2: Variable [definition]
        "1" @ 5..6: Number
        "AB" @ 7..9: Variable [definition, readonly]
        "1" @ 12..13: Number
        "ABC" @ 14..17: Variable [definition, readonly]
        "1" @ 20..21: Number
        "A1" @ 22..24: Variable [definition, readonly]
        "1" @ 27..28: Number
        "AB1" @ 29..32: Variable [definition, readonly]
        "1" @ 35..36: Number
        "ABC1" @ 37..41: Variable [definition, readonly]
        "1" @ 44..45: Number
        "A_B" @ 46..49: Variable [definition, readonly]
        "1" @ 52..53: Number
        "A1_B" @ 54..58: Variable [definition, readonly]
        "1" @ 61..62: Number
        "A_B1" @ 63..67: Variable [definition, readonly]
        "1" @ 70..71: Number
        "A_1" @ 72..75: Variable [definition, readonly]
        "1" @ 78..79: Number
        "#);
    }

    #[test]
    fn test_implicitly_concatenated_strings() {
        let test = SemanticTokenTest::new(
            r#"x = "hello" "world"
y = ("multi"