inline_values.rs

   1use std::{path::Path, sync::Arc};
   2
   3use dap::{Scope, StackFrame, Variable, requests::Variables};
   4use editor::{Editor, EditorMode, MultiBuffer};
   5use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};
   6use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_python, tree_sitter_rust};
   7use project::{FakeFs, Project};
   8use serde_json::json;
   9use unindent::Unindent as _;
  10use util::path;
  11
  12use crate::{
  13    debugger_panel::DebugPanel,
  14    tests::{active_debug_session_panel, init_test, init_test_workspace, start_debug_session},
  15};
  16
  17#[gpui::test]
  18async fn test_rust_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
  19    init_test(cx);
  20
  21    fn stack_frame_for_line(line: u64) -> dap::StackFrame {
  22        StackFrame {
  23            id: 1,
  24            name: "Stack Frame 1".into(),
  25            source: Some(dap::Source {
  26                name: Some("main.rs".into()),
  27                path: Some(path!("/project/main.rs").into()),
  28                source_reference: None,
  29                presentation_hint: None,
  30                origin: None,
  31                sources: None,
  32                adapter_data: None,
  33                checksums: None,
  34            }),
  35            line,
  36            column: 1,
  37            end_line: None,
  38            end_column: None,
  39            can_restart: None,
  40            instruction_pointer_reference: None,
  41            module_id: None,
  42            presentation_hint: None,
  43        }
  44    }
  45
  46    let fs = FakeFs::new(executor.clone());
  47    let source_code = r#"
  48static mut GLOBAL: usize = 1;
  49
  50fn main() {
  51    let x = 10;
  52    let value = 42;
  53    let y = 4;
  54    let tester = {
  55        let y = 10;
  56        let y = 5;
  57        let b = 3;
  58        vec![y, 20, 30]
  59    };
  60
  61    let caller = || {
  62        let x = 3;
  63        println!("x={}", x);
  64    };
  65
  66    caller();
  67
  68    unsafe {
  69        GLOBAL = 2;
  70    }
  71
  72    let result = value * 2 * x;
  73    println!("Simple test executed: value={}, result={}", value, result);
  74    assert!(true);
  75}
  76"#
  77    .unindent();
  78    fs.insert_tree(path!("/project"), json!({ "main.rs": source_code }))
  79        .await;
  80
  81    let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
  82    let workspace = init_test_workspace(&project, cx).await;
  83    workspace
  84        .update(cx, |workspace, window, cx| {
  85            workspace.focus_panel::<DebugPanel>(window, cx);
  86        })
  87        .unwrap();
  88    let cx = &mut VisualTestContext::from_window(*workspace, cx);
  89
  90    let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
  91    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
  92
  93    client.on_request::<dap::requests::Threads, _>(move |_, _| {
  94        Ok(dap::ThreadsResponse {
  95            threads: vec![dap::Thread {
  96                id: 1,
  97                name: "Thread 1".into(),
  98            }],
  99        })
 100    });
 101
 102    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 103        Ok(dap::StackTraceResponse {
 104            stack_frames: vec![stack_frame_for_line(4)],
 105            total_frames: None,
 106        })
 107    });
 108
 109    client.on_request::<dap::requests::Evaluate, _>(move |_, args| {
 110        assert_eq!("GLOBAL", args.expression);
 111        Ok(dap::EvaluateResponse {
 112            result: "1".into(),
 113            type_: None,
 114            presentation_hint: None,
 115            variables_reference: 0,
 116            named_variables: None,
 117            indexed_variables: None,
 118            memory_reference: None,
 119            value_location_reference: None,
 120        })
 121    });
 122
 123    let local_variables = vec![
 124        Variable {
 125            name: "x".into(),
 126            value: "10".into(),
 127            type_: None,
 128            presentation_hint: None,
 129            evaluate_name: None,
 130            variables_reference: 0,
 131            named_variables: None,
 132            indexed_variables: None,
 133            memory_reference: None,
 134            declaration_location_reference: None,
 135            value_location_reference: None,
 136        },
 137        Variable {
 138            name: "y".into(),
 139            value: "4".into(),
 140            type_: None,
 141            presentation_hint: None,
 142            evaluate_name: None,
 143            variables_reference: 0,
 144            named_variables: None,
 145            indexed_variables: None,
 146            memory_reference: None,
 147            declaration_location_reference: None,
 148            value_location_reference: None,
 149        },
 150        Variable {
 151            name: "value".into(),
 152            value: "42".into(),
 153            type_: None,
 154            presentation_hint: None,
 155            evaluate_name: None,
 156            variables_reference: 0,
 157            named_variables: None,
 158            indexed_variables: None,
 159            memory_reference: None,
 160            declaration_location_reference: None,
 161            value_location_reference: None,
 162        },
 163    ];
 164
 165    client.on_request::<Variables, _>({
 166        let local_variables = Arc::new(local_variables.clone());
 167        move |_, _| {
 168            Ok(dap::VariablesResponse {
 169                variables: (*local_variables).clone(),
 170            })
 171        }
 172    });
 173
 174    client.on_request::<dap::requests::Scopes, _>(move |_, _| {
 175        Ok(dap::ScopesResponse {
 176            scopes: vec![Scope {
 177                name: "Locale".into(),
 178                presentation_hint: None,
 179                variables_reference: 2,
 180                named_variables: None,
 181                indexed_variables: None,
 182                expensive: false,
 183                source: None,
 184                line: None,
 185                column: None,
 186                end_line: None,
 187                end_column: None,
 188            }],
 189        })
 190    });
 191
 192    client
 193        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 194            reason: dap::StoppedEventReason::Pause,
 195            description: None,
 196            thread_id: Some(1),
 197            preserve_focus_hint: None,
 198            text: None,
 199            all_threads_stopped: None,
 200            hit_breakpoint_ids: None,
 201        }))
 202        .await;
 203
 204    cx.run_until_parked();
 205
 206    let project_path = Path::new(path!("/project"));
 207    let worktree = project
 208        .update(cx, |project, cx| project.find_worktree(project_path, cx))
 209        .expect("This worktree should exist in project")
 210        .0;
 211
 212    let worktree_id = workspace
 213        .update(cx, |_, _, cx| worktree.read(cx).id())
 214        .unwrap();
 215
 216    let buffer = project
 217        .update(cx, |project, cx| {
 218            project.open_buffer((worktree_id, "main.rs"), cx)
 219        })
 220        .await
 221        .unwrap();
 222
 223    buffer.update(cx, |buffer, cx| {
 224        buffer.set_language(Some(Arc::new(rust_lang())), cx);
 225    });
 226
 227    let (editor, cx) = cx.add_window_view(|window, cx| {
 228        Editor::new(
 229            EditorMode::full(),
 230            MultiBuffer::build_from_buffer(buffer, cx),
 231            Some(project),
 232            window,
 233            cx,
 234        )
 235    });
 236
 237    active_debug_session_panel(workspace, cx).update_in(cx, |_, window, cx| {
 238        cx.focus_self(window);
 239    });
 240    cx.run_until_parked();
 241
 242    editor.update(cx, |editor, cx| editor.refresh_inline_values(cx));
 243
 244    cx.run_until_parked();
 245
 246    editor.update_in(cx, |editor, window, cx| {
 247        pretty_assertions::assert_eq!(
 248            r#"
 249    static mut GLOBAL: 1: usize = 1;
 250
 251    fn main() {
 252        let x = 10;
 253        let value = 42;
 254        let y = 4;
 255        let tester = {
 256            let y = 10;
 257            let y = 5;
 258            let b = 3;
 259            vec![y, 20, 30]
 260        };
 261
 262        let caller = || {
 263            let x = 3;
 264            println!("x={}", x);
 265        };
 266
 267        caller();
 268
 269        unsafe {
 270            GLOBAL = 2;
 271        }
 272
 273        let result = value * 2 * x;
 274        println!("Simple test executed: value={}, result={}", value, result);
 275        assert!(true);
 276    }
 277    "#
 278            .unindent(),
 279            editor.snapshot(window, cx).text()
 280        );
 281    });
 282
 283    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 284        Ok(dap::StackTraceResponse {
 285            stack_frames: vec![stack_frame_for_line(5)],
 286            total_frames: None,
 287        })
 288    });
 289    client
 290        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 291            reason: dap::StoppedEventReason::Pause,
 292            description: None,
 293            thread_id: Some(1),
 294            preserve_focus_hint: None,
 295            text: None,
 296            all_threads_stopped: None,
 297            hit_breakpoint_ids: None,
 298        }))
 299        .await;
 300
 301    cx.run_until_parked();
 302
 303    editor.update_in(cx, |editor, window, cx| {
 304        pretty_assertions::assert_eq!(
 305            r#"
 306    static mut GLOBAL: 1: usize = 1;
 307
 308    fn main() {
 309        let x: 10 = 10;
 310        let value = 42;
 311        let y = 4;
 312        let tester = {
 313            let y = 10;
 314            let y = 5;
 315            let b = 3;
 316            vec![y, 20, 30]
 317        };
 318
 319        let caller = || {
 320            let x = 3;
 321            println!("x={}", x);
 322        };
 323
 324        caller();
 325
 326        unsafe {
 327            GLOBAL = 2;
 328        }
 329
 330        let result = value * 2 * x;
 331        println!("Simple test executed: value={}, result={}", value, result);
 332        assert!(true);
 333    }
 334    "#
 335            .unindent(),
 336            editor.snapshot(window, cx).text()
 337        );
 338    });
 339
 340    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 341        Ok(dap::StackTraceResponse {
 342            stack_frames: vec![stack_frame_for_line(6)],
 343            total_frames: None,
 344        })
 345    });
 346    client
 347        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 348            reason: dap::StoppedEventReason::Pause,
 349            description: None,
 350            thread_id: Some(1),
 351            preserve_focus_hint: None,
 352            text: None,
 353            all_threads_stopped: None,
 354            hit_breakpoint_ids: None,
 355        }))
 356        .await;
 357
 358    cx.run_until_parked();
 359
 360    editor.update_in(cx, |editor, window, cx| {
 361        pretty_assertions::assert_eq!(
 362            r#"
 363    static mut GLOBAL: 1: usize = 1;
 364
 365    fn main() {
 366        let x: 10 = 10;
 367        let value: 42 = 42;
 368        let y = 4;
 369        let tester = {
 370            let y = 10;
 371            let y = 5;
 372            let b = 3;
 373            vec![y, 20, 30]
 374        };
 375
 376        let caller = || {
 377            let x = 3;
 378            println!("x={}", x);
 379        };
 380
 381        caller();
 382
 383        unsafe {
 384            GLOBAL = 2;
 385        }
 386
 387        let result = value * 2 * x;
 388        println!("Simple test executed: value={}, result={}", value, result);
 389        assert!(true);
 390    }
 391    "#
 392            .unindent(),
 393            editor.snapshot(window, cx).text()
 394        );
 395    });
 396
 397    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 398        Ok(dap::StackTraceResponse {
 399            stack_frames: vec![stack_frame_for_line(7)],
 400            total_frames: None,
 401        })
 402    });
 403    client
 404        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 405            reason: dap::StoppedEventReason::Pause,
 406            description: None,
 407            thread_id: Some(1),
 408            preserve_focus_hint: None,
 409            text: None,
 410            all_threads_stopped: None,
 411            hit_breakpoint_ids: None,
 412        }))
 413        .await;
 414
 415    cx.run_until_parked();
 416
 417    editor.update_in(cx, |editor, window, cx| {
 418        pretty_assertions::assert_eq!(
 419            r#"
 420    static mut GLOBAL: 1: usize = 1;
 421
 422    fn main() {
 423        let x: 10 = 10;
 424        let value: 42 = 42;
 425        let y: 4 = 4;
 426        let tester = {
 427            let y = 10;
 428            let y = 5;
 429            let b = 3;
 430            vec![y, 20, 30]
 431        };
 432
 433        let caller = || {
 434            let x = 3;
 435            println!("x={}", x);
 436        };
 437
 438        caller();
 439
 440        unsafe {
 441            GLOBAL = 2;
 442        }
 443
 444        let result = value * 2 * x;
 445        println!("Simple test executed: value={}, result={}", value, result);
 446        assert!(true);
 447    }
 448    "#
 449            .unindent(),
 450            editor.snapshot(window, cx).text()
 451        );
 452    });
 453
 454    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 455        Ok(dap::StackTraceResponse {
 456            stack_frames: vec![stack_frame_for_line(8)],
 457            total_frames: None,
 458        })
 459    });
 460    client
 461        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 462            reason: dap::StoppedEventReason::Pause,
 463            description: None,
 464            thread_id: Some(1),
 465            preserve_focus_hint: None,
 466            text: None,
 467            all_threads_stopped: None,
 468            hit_breakpoint_ids: None,
 469        }))
 470        .await;
 471
 472    cx.run_until_parked();
 473
 474    editor.update_in(cx, |editor, window, cx| {
 475        pretty_assertions::assert_eq!(
 476            r#"
 477    static mut GLOBAL: 1: usize = 1;
 478
 479    fn main() {
 480        let x: 10 = 10;
 481        let value: 42 = 42;
 482        let y: 4 = 4;
 483        let tester = {
 484            let y = 10;
 485            let y = 5;
 486            let b = 3;
 487            vec![y, 20, 30]
 488        };
 489
 490        let caller = || {
 491            let x = 3;
 492            println!("x={}", x);
 493        };
 494
 495        caller();
 496
 497        unsafe {
 498            GLOBAL = 2;
 499        }
 500
 501        let result = value * 2 * x;
 502        println!("Simple test executed: value={}, result={}", value, result);
 503        assert!(true);
 504    }
 505    "#
 506            .unindent(),
 507            editor.snapshot(window, cx).text()
 508        );
 509    });
 510
 511    let local_variables = vec![
 512        Variable {
 513            name: "x".into(),
 514            value: "10".into(),
 515            type_: None,
 516            presentation_hint: None,
 517            evaluate_name: None,
 518            variables_reference: 0,
 519            named_variables: None,
 520            indexed_variables: None,
 521            memory_reference: None,
 522            declaration_location_reference: None,
 523            value_location_reference: None,
 524        },
 525        Variable {
 526            name: "y".into(),
 527            value: "10".into(),
 528            type_: None,
 529            presentation_hint: None,
 530            evaluate_name: None,
 531            variables_reference: 0,
 532            named_variables: None,
 533            indexed_variables: None,
 534            memory_reference: None,
 535            declaration_location_reference: None,
 536            value_location_reference: None,
 537        },
 538        Variable {
 539            name: "value".into(),
 540            value: "42".into(),
 541            type_: None,
 542            presentation_hint: None,
 543            evaluate_name: None,
 544            variables_reference: 0,
 545            named_variables: None,
 546            indexed_variables: None,
 547            memory_reference: None,
 548            declaration_location_reference: None,
 549            value_location_reference: None,
 550        },
 551    ];
 552
 553    client.on_request::<Variables, _>({
 554        let local_variables = Arc::new(local_variables.clone());
 555        move |_, _| {
 556            Ok(dap::VariablesResponse {
 557                variables: (*local_variables).clone(),
 558            })
 559        }
 560    });
 561    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 562        Ok(dap::StackTraceResponse {
 563            stack_frames: vec![stack_frame_for_line(9)],
 564            total_frames: None,
 565        })
 566    });
 567    client
 568        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 569            reason: dap::StoppedEventReason::Pause,
 570            description: None,
 571            thread_id: Some(1),
 572            preserve_focus_hint: None,
 573            text: None,
 574            all_threads_stopped: None,
 575            hit_breakpoint_ids: None,
 576        }))
 577        .await;
 578
 579    cx.run_until_parked();
 580
 581    editor.update_in(cx, |editor, window, cx| {
 582        pretty_assertions::assert_eq!(
 583            r#"
 584    static mut GLOBAL: 1: usize = 1;
 585
 586    fn main() {
 587        let x: 10 = 10;
 588        let value: 42 = 42;
 589        let y = 4;
 590        let tester = {
 591            let y: 10 = 10;
 592            let y = 5;
 593            let b = 3;
 594            vec![y, 20, 30]
 595        };
 596
 597        let caller = || {
 598            let x = 3;
 599            println!("x={}", x);
 600        };
 601
 602        caller();
 603
 604        unsafe {
 605            GLOBAL = 2;
 606        }
 607
 608        let result = value * 2 * x;
 609        println!("Simple test executed: value={}, result={}", value, result);
 610        assert!(true);
 611    }
 612    "#
 613            .unindent(),
 614            editor.snapshot(window, cx).text()
 615        );
 616    });
 617
 618    let local_variables = vec![
 619        Variable {
 620            name: "x".into(),
 621            value: "10".into(),
 622            type_: None,
 623            presentation_hint: None,
 624            evaluate_name: None,
 625            variables_reference: 0,
 626            named_variables: None,
 627            indexed_variables: None,
 628            memory_reference: None,
 629            declaration_location_reference: None,
 630            value_location_reference: None,
 631        },
 632        Variable {
 633            name: "y".into(),
 634            value: "5".into(),
 635            type_: None,
 636            presentation_hint: None,
 637            evaluate_name: None,
 638            variables_reference: 0,
 639            named_variables: None,
 640            indexed_variables: None,
 641            memory_reference: None,
 642            declaration_location_reference: None,
 643            value_location_reference: None,
 644        },
 645        Variable {
 646            name: "value".into(),
 647            value: "42".into(),
 648            type_: None,
 649            presentation_hint: None,
 650            evaluate_name: None,
 651            variables_reference: 0,
 652            named_variables: None,
 653            indexed_variables: None,
 654            memory_reference: None,
 655            declaration_location_reference: None,
 656            value_location_reference: None,
 657        },
 658    ];
 659
 660    client.on_request::<Variables, _>({
 661        let local_variables = Arc::new(local_variables.clone());
 662        move |_, _| {
 663            Ok(dap::VariablesResponse {
 664                variables: (*local_variables).clone(),
 665            })
 666        }
 667    });
 668    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 669        Ok(dap::StackTraceResponse {
 670            stack_frames: vec![stack_frame_for_line(10)],
 671            total_frames: None,
 672        })
 673    });
 674    client
 675        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 676            reason: dap::StoppedEventReason::Pause,
 677            description: None,
 678            thread_id: Some(1),
 679            preserve_focus_hint: None,
 680            text: None,
 681            all_threads_stopped: None,
 682            hit_breakpoint_ids: None,
 683        }))
 684        .await;
 685
 686    cx.run_until_parked();
 687
 688    editor.update_in(cx, |editor, window, cx| {
 689        pretty_assertions::assert_eq!(
 690            r#"
 691    static mut GLOBAL: 1: usize = 1;
 692
 693    fn main() {
 694        let x: 10 = 10;
 695        let value: 42 = 42;
 696        let y = 4;
 697        let tester = {
 698            let y = 10;
 699            let y: 5 = 5;
 700            let b = 3;
 701            vec![y, 20, 30]
 702        };
 703
 704        let caller = || {
 705            let x = 3;
 706            println!("x={}", x);
 707        };
 708
 709        caller();
 710
 711        unsafe {
 712            GLOBAL = 2;
 713        }
 714
 715        let result = value * 2 * x;
 716        println!("Simple test executed: value={}, result={}", value, result);
 717        assert!(true);
 718    }
 719    "#
 720            .unindent(),
 721            editor.snapshot(window, cx).text()
 722        );
 723    });
 724
 725    let local_variables = vec![
 726        Variable {
 727            name: "x".into(),
 728            value: "10".into(),
 729            type_: None,
 730            presentation_hint: None,
 731            evaluate_name: None,
 732            variables_reference: 0,
 733            named_variables: None,
 734            indexed_variables: None,
 735            memory_reference: None,
 736            declaration_location_reference: None,
 737            value_location_reference: None,
 738        },
 739        Variable {
 740            name: "y".into(),
 741            value: "5".into(),
 742            type_: None,
 743            presentation_hint: None,
 744            evaluate_name: None,
 745            variables_reference: 0,
 746            named_variables: None,
 747            indexed_variables: None,
 748            memory_reference: None,
 749            declaration_location_reference: None,
 750            value_location_reference: None,
 751        },
 752        Variable {
 753            name: "value".into(),
 754            value: "42".into(),
 755            type_: None,
 756            presentation_hint: None,
 757            evaluate_name: None,
 758            variables_reference: 0,
 759            named_variables: None,
 760            indexed_variables: None,
 761            memory_reference: None,
 762            declaration_location_reference: None,
 763            value_location_reference: None,
 764        },
 765        Variable {
 766            name: "b".into(),
 767            value: "3".into(),
 768            type_: None,
 769            presentation_hint: None,
 770            evaluate_name: None,
 771            variables_reference: 0,
 772            named_variables: None,
 773            indexed_variables: None,
 774            memory_reference: None,
 775            declaration_location_reference: None,
 776            value_location_reference: None,
 777        },
 778    ];
 779    client.on_request::<Variables, _>({
 780        let local_variables = Arc::new(local_variables.clone());
 781        move |_, _| {
 782            Ok(dap::VariablesResponse {
 783                variables: (*local_variables).clone(),
 784            })
 785        }
 786    });
 787    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 788        Ok(dap::StackTraceResponse {
 789            stack_frames: vec![stack_frame_for_line(11)],
 790            total_frames: None,
 791        })
 792    });
 793    client
 794        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 795            reason: dap::StoppedEventReason::Pause,
 796            description: None,
 797            thread_id: Some(1),
 798            preserve_focus_hint: None,
 799            text: None,
 800            all_threads_stopped: None,
 801            hit_breakpoint_ids: None,
 802        }))
 803        .await;
 804
 805    cx.run_until_parked();
 806
 807    editor.update_in(cx, |editor, window, cx| {
 808        pretty_assertions::assert_eq!(
 809            r#"
 810    static mut GLOBAL: 1: usize = 1;
 811
 812    fn main() {
 813        let x: 10 = 10;
 814        let value: 42 = 42;
 815        let y = 4;
 816        let tester = {
 817            let y = 10;
 818            let y: 5 = 5;
 819            let b: 3 = 3;
 820            vec![y, 20, 30]
 821        };
 822
 823        let caller = || {
 824            let x = 3;
 825            println!("x={}", x);
 826        };
 827
 828        caller();
 829
 830        unsafe {
 831            GLOBAL = 2;
 832        }
 833
 834        let result = value * 2 * x;
 835        println!("Simple test executed: value={}, result={}", value, result);
 836        assert!(true);
 837    }
 838    "#
 839            .unindent(),
 840            editor.snapshot(window, cx).text()
 841        );
 842    });
 843
 844    let local_variables = vec![
 845        Variable {
 846            name: "x".into(),
 847            value: "10".into(),
 848            type_: None,
 849            presentation_hint: None,
 850            evaluate_name: None,
 851            variables_reference: 0,
 852            named_variables: None,
 853            indexed_variables: None,
 854            memory_reference: None,
 855            declaration_location_reference: None,
 856            value_location_reference: None,
 857        },
 858        Variable {
 859            name: "y".into(),
 860            value: "4".into(),
 861            type_: None,
 862            presentation_hint: None,
 863            evaluate_name: None,
 864            variables_reference: 0,
 865            named_variables: None,
 866            indexed_variables: None,
 867            memory_reference: None,
 868            declaration_location_reference: None,
 869            value_location_reference: None,
 870        },
 871        Variable {
 872            name: "value".into(),
 873            value: "42".into(),
 874            type_: None,
 875            presentation_hint: None,
 876            evaluate_name: None,
 877            variables_reference: 0,
 878            named_variables: None,
 879            indexed_variables: None,
 880            memory_reference: None,
 881            declaration_location_reference: None,
 882            value_location_reference: None,
 883        },
 884        Variable {
 885            name: "tester".into(),
 886            value: "size=3".into(),
 887            type_: None,
 888            presentation_hint: None,
 889            evaluate_name: None,
 890            variables_reference: 0,
 891            named_variables: None,
 892            indexed_variables: None,
 893            memory_reference: None,
 894            declaration_location_reference: None,
 895            value_location_reference: None,
 896        },
 897    ];
 898    client.on_request::<Variables, _>({
 899        let local_variables = Arc::new(local_variables.clone());
 900        move |_, _| {
 901            Ok(dap::VariablesResponse {
 902                variables: (*local_variables).clone(),
 903            })
 904        }
 905    });
 906    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
 907        Ok(dap::StackTraceResponse {
 908            stack_frames: vec![stack_frame_for_line(14)],
 909            total_frames: None,
 910        })
 911    });
 912    client
 913        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
 914            reason: dap::StoppedEventReason::Pause,
 915            description: None,
 916            thread_id: Some(1),
 917            preserve_focus_hint: None,
 918            text: None,
 919            all_threads_stopped: None,
 920            hit_breakpoint_ids: None,
 921        }))
 922        .await;
 923
 924    cx.run_until_parked();
 925
 926    editor.update_in(cx, |editor, window, cx| {
 927        pretty_assertions::assert_eq!(
 928            r#"
 929    static mut GLOBAL: 1: usize = 1;
 930
 931    fn main() {
 932        let x: 10 = 10;
 933        let value: 42 = 42;
 934        let y: 4 = 4;
 935        let tester: size=3 = {
 936            let y = 10;
 937            let y = 5;
 938            let b = 3;
 939            vec![y, 20, 30]
 940        };
 941
 942        let caller = || {
 943            let x = 3;
 944            println!("x={}", x);
 945        };
 946
 947        caller();
 948
 949        unsafe {
 950            GLOBAL = 2;
 951        }
 952
 953        let result = value * 2 * x;
 954        println!("Simple test executed: value={}, result={}", value, result);
 955        assert!(true);
 956    }
 957    "#
 958            .unindent(),
 959            editor.snapshot(window, cx).text()
 960        );
 961    });
 962
 963    let local_variables = vec![
 964        Variable {
 965            name: "x".into(),
 966            value: "10".into(),
 967            type_: None,
 968            presentation_hint: None,
 969            evaluate_name: None,
 970            variables_reference: 0,
 971            named_variables: None,
 972            indexed_variables: None,
 973            memory_reference: None,
 974            declaration_location_reference: None,
 975            value_location_reference: None,
 976        },
 977        Variable {
 978            name: "y".into(),
 979            value: "4".into(),
 980            type_: None,
 981            presentation_hint: None,
 982            evaluate_name: None,
 983            variables_reference: 0,
 984            named_variables: None,
 985            indexed_variables: None,
 986            memory_reference: None,
 987            declaration_location_reference: None,
 988            value_location_reference: None,
 989        },
 990        Variable {
 991            name: "value".into(),
 992            value: "42".into(),
 993            type_: None,
 994            presentation_hint: None,
 995            evaluate_name: None,
 996            variables_reference: 0,
 997            named_variables: None,
 998            indexed_variables: None,
 999            memory_reference: None,
1000            declaration_location_reference: None,
1001            value_location_reference: None,
1002        },
1003        Variable {
1004            name: "tester".into(),
1005            value: "size=3".into(),
1006            type_: None,
1007            presentation_hint: None,
1008            evaluate_name: None,
1009            variables_reference: 0,
1010            named_variables: None,
1011            indexed_variables: None,
1012            memory_reference: None,
1013            declaration_location_reference: None,
1014            value_location_reference: None,
1015        },
1016        Variable {
1017            name: "caller".into(),
1018            value: "<not available>".into(),
1019            type_: None,
1020            presentation_hint: None,
1021            evaluate_name: None,
1022            variables_reference: 0,
1023            named_variables: None,
1024            indexed_variables: None,
1025            memory_reference: None,
1026            declaration_location_reference: None,
1027            value_location_reference: None,
1028        },
1029    ];
1030    client.on_request::<Variables, _>({
1031        let local_variables = Arc::new(local_variables.clone());
1032        move |_, _| {
1033            Ok(dap::VariablesResponse {
1034                variables: (*local_variables).clone(),
1035            })
1036        }
1037    });
1038    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1039        Ok(dap::StackTraceResponse {
1040            stack_frames: vec![stack_frame_for_line(19)],
1041            total_frames: None,
1042        })
1043    });
1044    client
1045        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1046            reason: dap::StoppedEventReason::Pause,
1047            description: None,
1048            thread_id: Some(1),
1049            preserve_focus_hint: None,
1050            text: None,
1051            all_threads_stopped: None,
1052            hit_breakpoint_ids: None,
1053        }))
1054        .await;
1055
1056    cx.run_until_parked();
1057
1058    editor.update_in(cx, |editor, window, cx| {
1059        pretty_assertions::assert_eq!(
1060            r#"
1061    static mut GLOBAL: 1: usize = 1;
1062
1063    fn main() {
1064        let x: 10 = 10;
1065        let value: 42 = 42;
1066        let y: 4 = 4;
1067        let tester: size=3 = {
1068            let y = 10;
1069            let y = 5;
1070            let b = 3;
1071            vec![y, 20, 30]
1072        };
1073
1074        let caller: <not available> = || {
1075            let x = 3;
1076            println!("x={}", x);
1077        };
1078
1079        caller();
1080
1081        unsafe {
1082            GLOBAL = 2;
1083        }
1084
1085        let result = value * 2 * x;
1086        println!("Simple test executed: value={}, result={}", value, result);
1087        assert!(true);
1088    }
1089    "#
1090            .unindent(),
1091            editor.snapshot(window, cx).text()
1092        );
1093    });
1094
1095    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1096        Ok(dap::StackTraceResponse {
1097            stack_frames: vec![stack_frame_for_line(15)],
1098            total_frames: None,
1099        })
1100    });
1101    client
1102        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1103            reason: dap::StoppedEventReason::Pause,
1104            description: None,
1105            thread_id: Some(1),
1106            preserve_focus_hint: None,
1107            text: None,
1108            all_threads_stopped: None,
1109            hit_breakpoint_ids: None,
1110        }))
1111        .await;
1112
1113    cx.run_until_parked();
1114
1115    editor.update_in(cx, |editor, window, cx| {
1116        pretty_assertions::assert_eq!(
1117            r#"
1118    static mut GLOBAL: 1: usize = 1;
1119
1120    fn main() {
1121        let x = 10;
1122        let value = 42;
1123        let y = 4;
1124        let tester = {
1125            let y = 10;
1126            let y = 5;
1127            let b = 3;
1128            vec![y, 20, 30]
1129        };
1130
1131        let caller = || {
1132            let x = 3;
1133            println!("x={}", x);
1134        };
1135
1136        caller();
1137
1138        unsafe {
1139            GLOBAL = 2;
1140        }
1141
1142        let result = value * 2 * x;
1143        println!("Simple test executed: value={}, result={}", value, result);
1144        assert!(true);
1145    }
1146    "#
1147            .unindent(),
1148            editor.snapshot(window, cx).text()
1149        );
1150    });
1151
1152    let local_variables = vec![Variable {
1153        name: "x".into(),
1154        value: "3".into(),
1155        type_: None,
1156        presentation_hint: None,
1157        evaluate_name: None,
1158        variables_reference: 0,
1159        named_variables: None,
1160        indexed_variables: None,
1161        memory_reference: None,
1162        declaration_location_reference: None,
1163        value_location_reference: None,
1164    }];
1165    client.on_request::<Variables, _>({
1166        let local_variables = Arc::new(local_variables.clone());
1167        move |_, _| {
1168            Ok(dap::VariablesResponse {
1169                variables: (*local_variables).clone(),
1170            })
1171        }
1172    });
1173    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1174        Ok(dap::StackTraceResponse {
1175            stack_frames: vec![stack_frame_for_line(16)],
1176            total_frames: None,
1177        })
1178    });
1179    client
1180        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1181            reason: dap::StoppedEventReason::Pause,
1182            description: None,
1183            thread_id: Some(1),
1184            preserve_focus_hint: None,
1185            text: None,
1186            all_threads_stopped: None,
1187            hit_breakpoint_ids: None,
1188        }))
1189        .await;
1190
1191    cx.run_until_parked();
1192
1193    editor.update_in(cx, |editor, window, cx| {
1194        pretty_assertions::assert_eq!(
1195            r#"
1196    static mut GLOBAL: 1: usize = 1;
1197
1198    fn main() {
1199        let x = 10;
1200        let value = 42;
1201        let y = 4;
1202        let tester = {
1203            let y = 10;
1204            let y = 5;
1205            let b = 3;
1206            vec![y, 20, 30]
1207        };
1208
1209        let caller = || {
1210            let x: 3 = 3;
1211            println!("x={}", x);
1212        };
1213
1214        caller();
1215
1216        unsafe {
1217            GLOBAL = 2;
1218        }
1219
1220        let result = value * 2 * x;
1221        println!("Simple test executed: value={}, result={}", value, result);
1222        assert!(true);
1223    }
1224    "#
1225            .unindent(),
1226            editor.snapshot(window, cx).text()
1227        );
1228    });
1229
1230    let local_variables = vec![
1231        Variable {
1232            name: "x".into(),
1233            value: "10".into(),
1234            type_: None,
1235            presentation_hint: None,
1236            evaluate_name: None,
1237            variables_reference: 0,
1238            named_variables: None,
1239            indexed_variables: None,
1240            memory_reference: None,
1241            declaration_location_reference: None,
1242            value_location_reference: None,
1243        },
1244        Variable {
1245            name: "y".into(),
1246            value: "4".into(),
1247            type_: None,
1248            presentation_hint: None,
1249            evaluate_name: None,
1250            variables_reference: 0,
1251            named_variables: None,
1252            indexed_variables: None,
1253            memory_reference: None,
1254            declaration_location_reference: None,
1255            value_location_reference: None,
1256        },
1257        Variable {
1258            name: "value".into(),
1259            value: "42".into(),
1260            type_: None,
1261            presentation_hint: None,
1262            evaluate_name: None,
1263            variables_reference: 0,
1264            named_variables: None,
1265            indexed_variables: None,
1266            memory_reference: None,
1267            declaration_location_reference: None,
1268            value_location_reference: None,
1269        },
1270        Variable {
1271            name: "tester".into(),
1272            value: "size=3".into(),
1273            type_: None,
1274            presentation_hint: None,
1275            evaluate_name: None,
1276            variables_reference: 0,
1277            named_variables: None,
1278            indexed_variables: None,
1279            memory_reference: None,
1280            declaration_location_reference: None,
1281            value_location_reference: None,
1282        },
1283        Variable {
1284            name: "caller".into(),
1285            value: "<not available>".into(),
1286            type_: None,
1287            presentation_hint: None,
1288            evaluate_name: None,
1289            variables_reference: 0,
1290            named_variables: None,
1291            indexed_variables: None,
1292            memory_reference: None,
1293            declaration_location_reference: None,
1294            value_location_reference: None,
1295        },
1296    ];
1297    client.on_request::<Variables, _>({
1298        let local_variables = Arc::new(local_variables.clone());
1299        move |_, _| {
1300            Ok(dap::VariablesResponse {
1301                variables: (*local_variables).clone(),
1302            })
1303        }
1304    });
1305    client.on_request::<dap::requests::Evaluate, _>(move |_, args| {
1306        assert_eq!("GLOBAL", args.expression);
1307        Ok(dap::EvaluateResponse {
1308            result: "2".into(),
1309            type_: None,
1310            presentation_hint: None,
1311            variables_reference: 0,
1312            named_variables: None,
1313            indexed_variables: None,
1314            memory_reference: None,
1315            value_location_reference: None,
1316        })
1317    });
1318    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1319        Ok(dap::StackTraceResponse {
1320            stack_frames: vec![stack_frame_for_line(25)],
1321            total_frames: None,
1322        })
1323    });
1324    client
1325        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1326            reason: dap::StoppedEventReason::Pause,
1327            description: None,
1328            thread_id: Some(1),
1329            preserve_focus_hint: None,
1330            text: None,
1331            all_threads_stopped: None,
1332            hit_breakpoint_ids: None,
1333        }))
1334        .await;
1335
1336    cx.run_until_parked();
1337
1338    editor.update_in(cx, |editor, window, cx| {
1339        pretty_assertions::assert_eq!(
1340            r#"
1341    static mut GLOBAL: 2: usize = 1;
1342
1343    fn main() {
1344        let x: 10 = 10;
1345        let value: 42 = 42;
1346        let y: 4 = 4;
1347        let tester: size=3 = {
1348            let y = 10;
1349            let y = 5;
1350            let b = 3;
1351            vec![y, 20, 30]
1352        };
1353
1354        let caller: <not available> = || {
1355            let x = 3;
1356            println!("x={}", x);
1357        };
1358
1359        caller();
1360
1361        unsafe {
1362            GLOBAL = 2;
1363        }
1364
1365        let result = value * 2 * x;
1366        println!("Simple test executed: value={}, result={}", value, result);
1367        assert!(true);
1368    }
1369    "#
1370            .unindent(),
1371            editor.snapshot(window, cx).text()
1372        );
1373    });
1374
1375    let local_variables = vec![
1376        Variable {
1377            name: "x".into(),
1378            value: "10".into(),
1379            type_: None,
1380            presentation_hint: None,
1381            evaluate_name: None,
1382            variables_reference: 0,
1383            named_variables: None,
1384            indexed_variables: None,
1385            memory_reference: None,
1386            declaration_location_reference: None,
1387            value_location_reference: None,
1388        },
1389        Variable {
1390            name: "y".into(),
1391            value: "4".into(),
1392            type_: None,
1393            presentation_hint: None,
1394            evaluate_name: None,
1395            variables_reference: 0,
1396            named_variables: None,
1397            indexed_variables: None,
1398            memory_reference: None,
1399            declaration_location_reference: None,
1400            value_location_reference: None,
1401        },
1402        Variable {
1403            name: "value".into(),
1404            value: "42".into(),
1405            type_: None,
1406            presentation_hint: None,
1407            evaluate_name: None,
1408            variables_reference: 0,
1409            named_variables: None,
1410            indexed_variables: None,
1411            memory_reference: None,
1412            declaration_location_reference: None,
1413            value_location_reference: None,
1414        },
1415        Variable {
1416            name: "tester".into(),
1417            value: "size=3".into(),
1418            type_: None,
1419            presentation_hint: None,
1420            evaluate_name: None,
1421            variables_reference: 0,
1422            named_variables: None,
1423            indexed_variables: None,
1424            memory_reference: None,
1425            declaration_location_reference: None,
1426            value_location_reference: None,
1427        },
1428        Variable {
1429            name: "caller".into(),
1430            value: "<not available>".into(),
1431            type_: None,
1432            presentation_hint: None,
1433            evaluate_name: None,
1434            variables_reference: 0,
1435            named_variables: None,
1436            indexed_variables: None,
1437            memory_reference: None,
1438            declaration_location_reference: None,
1439            value_location_reference: None,
1440        },
1441        Variable {
1442            name: "result".into(),
1443            value: "840".into(),
1444            type_: None,
1445            presentation_hint: None,
1446            evaluate_name: None,
1447            variables_reference: 0,
1448            named_variables: None,
1449            indexed_variables: None,
1450            memory_reference: None,
1451            declaration_location_reference: None,
1452            value_location_reference: None,
1453        },
1454    ];
1455    client.on_request::<Variables, _>({
1456        let local_variables = Arc::new(local_variables.clone());
1457        move |_, _| {
1458            Ok(dap::VariablesResponse {
1459                variables: (*local_variables).clone(),
1460            })
1461        }
1462    });
1463    client.on_request::<dap::requests::StackTrace, _>(move |_, _| {
1464        Ok(dap::StackTraceResponse {
1465            stack_frames: vec![stack_frame_for_line(26)],
1466            total_frames: None,
1467        })
1468    });
1469    client
1470        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1471            reason: dap::StoppedEventReason::Pause,
1472            description: None,
1473            thread_id: Some(1),
1474            preserve_focus_hint: None,
1475            text: None,
1476            all_threads_stopped: None,
1477            hit_breakpoint_ids: None,
1478        }))
1479        .await;
1480
1481    cx.run_until_parked();
1482
1483    editor.update_in(cx, |editor, window, cx| {
1484        pretty_assertions::assert_eq!(
1485            r#"
1486    static mut GLOBAL: 2: usize = 1;
1487
1488    fn main() {
1489        let x: 10 = 10;
1490        let value: 42 = 42;
1491        let y: 4 = 4;
1492        let tester: size=3 = {
1493            let y = 10;
1494            let y = 5;
1495            let b = 3;
1496            vec![y, 20, 30]
1497        };
1498
1499        let caller: <not available> = || {
1500            let x = 3;
1501            println!("x={}", x);
1502        };
1503
1504        caller();
1505
1506        unsafe {
1507            GLOBAL = 2;
1508        }
1509
1510        let result: 840 = value * 2 * x;
1511        println!("Simple test executed: value={}, result={}", value, result);
1512        assert!(true);
1513    }
1514    "#
1515            .unindent(),
1516            editor.snapshot(window, cx).text()
1517        );
1518    });
1519}
1520
1521fn rust_lang() -> Language {
1522    Language::new(
1523        LanguageConfig {
1524            name: "Rust".into(),
1525            matcher: LanguageMatcher {
1526                path_suffixes: vec!["rs".to_string()],
1527                ..Default::default()
1528            },
1529            ..Default::default()
1530        },
1531        Some(tree_sitter_rust::LANGUAGE.into()),
1532    )
1533}
1534
1535#[gpui::test]
1536async fn test_python_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
1537    init_test(cx);
1538
1539    let fs = FakeFs::new(executor.clone());
1540    let source_code = r#"
1541def process_data(untyped_param, typed_param: int, another_typed: str):
1542    # Local variables
1543    x = 10
1544    result = typed_param * 2
1545    text = "Hello, " + another_typed
1546
1547    # For loop with range
1548    sum_value = 0
1549    for i in range(5):
1550        sum_value += i
1551
1552    # Final result
1553    final_result = x + result + sum_value
1554    return final_result
1555"#
1556    .unindent();
1557    fs.insert_tree(path!("/project"), json!({ "main.py": source_code }))
1558        .await;
1559
1560    let project = Project::test(fs.clone(), [path!("/project").as_ref()], cx).await;
1561    let workspace = init_test_workspace(&project, cx).await;
1562    workspace
1563        .update(cx, |workspace, window, cx| {
1564            workspace.focus_panel::<DebugPanel>(window, cx);
1565        })
1566        .unwrap();
1567    let cx = &mut VisualTestContext::from_window(*workspace, cx);
1568
1569    let session = start_debug_session(&workspace, cx, |_| {}).unwrap();
1570    let client = session.update(cx, |session, _| session.adapter_client().unwrap());
1571
1572    let project_path = Path::new(path!("/project"));
1573    let worktree = project
1574        .update(cx, |project, cx| project.find_worktree(project_path, cx))
1575        .expect("This worktree should exist in project")
1576        .0;
1577
1578    let worktree_id = workspace
1579        .update(cx, |_, _, cx| worktree.read(cx).id())
1580        .unwrap();
1581
1582    let buffer = project
1583        .update(cx, |project, cx| {
1584            project.open_buffer((worktree_id, "main.py"), cx)
1585        })
1586        .await
1587        .unwrap();
1588
1589    buffer.update(cx, |buffer, cx| {
1590        buffer.set_language(Some(Arc::new(python_lang())), cx);
1591    });
1592
1593    let (editor, cx) = cx.add_window_view(|window, cx| {
1594        Editor::new(
1595            EditorMode::full(),
1596            MultiBuffer::build_from_buffer(buffer, cx),
1597            Some(project),
1598            window,
1599            cx,
1600        )
1601    });
1602
1603    editor.update(cx, |editor, cx| editor.refresh_inline_values(cx));
1604
1605    client.on_request::<dap::requests::Threads, _>(move |_, _| {
1606        Ok(dap::ThreadsResponse {
1607            threads: vec![dap::Thread {
1608                id: 1,
1609                name: "Thread 1".into(),
1610            }],
1611        })
1612    });
1613
1614    client.on_request::<dap::requests::StackTrace, _>(move |_, args| {
1615        assert_eq!(args.thread_id, 1);
1616        Ok(dap::StackTraceResponse {
1617            stack_frames: vec![StackFrame {
1618                id: 1,
1619                name: "Stack Frame 1".into(),
1620                source: Some(dap::Source {
1621                    name: Some("main.py".into()),
1622                    path: Some(path!("/project/main.py").into()),
1623                    source_reference: None,
1624                    presentation_hint: None,
1625                    origin: None,
1626                    sources: None,
1627                    adapter_data: None,
1628                    checksums: None,
1629                }),
1630                line: 12,
1631                column: 1,
1632                end_line: None,
1633                end_column: None,
1634                can_restart: None,
1635                instruction_pointer_reference: None,
1636                module_id: None,
1637                presentation_hint: None,
1638            }],
1639            total_frames: None,
1640        })
1641    });
1642
1643    client.on_request::<dap::requests::Scopes, _>(move |_, _| {
1644        Ok(dap::ScopesResponse {
1645            scopes: vec![
1646                Scope {
1647                    name: "Local".into(),
1648                    presentation_hint: None,
1649                    variables_reference: 1,
1650                    named_variables: None,
1651                    indexed_variables: None,
1652                    expensive: false,
1653                    source: None,
1654                    line: None,
1655                    column: None,
1656                    end_line: None,
1657                    end_column: None,
1658                },
1659                Scope {
1660                    name: "Global".into(),
1661                    presentation_hint: None,
1662                    variables_reference: 2,
1663                    named_variables: None,
1664                    indexed_variables: None,
1665                    expensive: false,
1666                    source: None,
1667                    line: None,
1668                    column: None,
1669                    end_line: None,
1670                    end_column: None,
1671                },
1672            ],
1673        })
1674    });
1675
1676    client.on_request::<Variables, _>(move |_, args| match args.variables_reference {
1677        1 => Ok(dap::VariablesResponse {
1678            variables: vec![
1679                Variable {
1680                    name: "untyped_param".into(),
1681                    value: "test_value".into(),
1682                    type_: Some("str".into()),
1683                    presentation_hint: None,
1684                    evaluate_name: None,
1685                    variables_reference: 0,
1686                    named_variables: None,
1687                    indexed_variables: None,
1688                    memory_reference: None,
1689                    declaration_location_reference: None,
1690                    value_location_reference: None,
1691                },
1692                Variable {
1693                    name: "typed_param".into(),
1694                    value: "42".into(),
1695                    type_: Some("int".into()),
1696                    presentation_hint: None,
1697                    evaluate_name: None,
1698                    variables_reference: 0,
1699                    named_variables: None,
1700                    indexed_variables: None,
1701                    memory_reference: None,
1702                    declaration_location_reference: None,
1703                    value_location_reference: None,
1704                },
1705                Variable {
1706                    name: "another_typed".into(),
1707                    value: "world".into(),
1708                    type_: Some("str".into()),
1709                    presentation_hint: None,
1710                    evaluate_name: None,
1711                    variables_reference: 0,
1712                    named_variables: None,
1713                    indexed_variables: None,
1714                    memory_reference: None,
1715                    declaration_location_reference: None,
1716                    value_location_reference: None,
1717                },
1718                Variable {
1719                    name: "x".into(),
1720                    value: "10".into(),
1721                    type_: Some("int".into()),
1722                    presentation_hint: None,
1723                    evaluate_name: None,
1724                    variables_reference: 0,
1725                    named_variables: None,
1726                    indexed_variables: None,
1727                    memory_reference: None,
1728                    declaration_location_reference: None,
1729                    value_location_reference: None,
1730                },
1731                Variable {
1732                    name: "result".into(),
1733                    value: "84".into(),
1734                    type_: Some("int".into()),
1735                    presentation_hint: None,
1736                    evaluate_name: None,
1737                    variables_reference: 0,
1738                    named_variables: None,
1739                    indexed_variables: None,
1740                    memory_reference: None,
1741                    declaration_location_reference: None,
1742                    value_location_reference: None,
1743                },
1744                Variable {
1745                    name: "text".into(),
1746                    value: "Hello, world".into(),
1747                    type_: Some("str".into()),
1748                    presentation_hint: None,
1749                    evaluate_name: None,
1750                    variables_reference: 0,
1751                    named_variables: None,
1752                    indexed_variables: None,
1753                    memory_reference: None,
1754                    declaration_location_reference: None,
1755                    value_location_reference: None,
1756                },
1757                Variable {
1758                    name: "sum_value".into(),
1759                    value: "10".into(),
1760                    type_: Some("int".into()),
1761                    presentation_hint: None,
1762                    evaluate_name: None,
1763                    variables_reference: 0,
1764                    named_variables: None,
1765                    indexed_variables: None,
1766                    memory_reference: None,
1767                    declaration_location_reference: None,
1768                    value_location_reference: None,
1769                },
1770                Variable {
1771                    name: "i".into(),
1772                    value: "4".into(),
1773                    type_: Some("int".into()),
1774                    presentation_hint: None,
1775                    evaluate_name: None,
1776                    variables_reference: 0,
1777                    named_variables: None,
1778                    indexed_variables: None,
1779                    memory_reference: None,
1780                    declaration_location_reference: None,
1781                    value_location_reference: None,
1782                },
1783                Variable {
1784                    name: "final_result".into(),
1785                    value: "104".into(),
1786                    type_: Some("int".into()),
1787                    presentation_hint: None,
1788                    evaluate_name: None,
1789                    variables_reference: 0,
1790                    named_variables: None,
1791                    indexed_variables: None,
1792                    memory_reference: None,
1793                    declaration_location_reference: None,
1794                    value_location_reference: None,
1795                },
1796            ],
1797        }),
1798        _ => Ok(dap::VariablesResponse { variables: vec![] }),
1799    });
1800
1801    client
1802        .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent {
1803            reason: dap::StoppedEventReason::Pause,
1804            description: None,
1805            thread_id: Some(1),
1806            preserve_focus_hint: None,
1807            text: None,
1808            all_threads_stopped: None,
1809            hit_breakpoint_ids: None,
1810        }))
1811        .await;
1812
1813    cx.run_until_parked();
1814
1815    editor.update_in(cx, |editor, window, cx| {
1816        pretty_assertions::assert_eq!(
1817            r#"
1818        def process_data(untyped_param: test_value, typed_param: 42: int, another_typed: world: str):
1819            # Local variables
1820            x: 10 = 10
1821            result: 84 = typed_param * 2
1822            text: Hello, world = "Hello, " + another_typed
1823
1824            # For loop with range
1825            sum_value: 10 = 0
1826            for i: 4 in range(5):
1827                sum_value += i
1828
1829            # Final result
1830            final_result = x + result + sum_value
1831            return final_result
1832        "#
1833            .unindent(),
1834            editor.snapshot(window, cx).text()
1835        );
1836    });
1837}
1838
1839fn python_lang() -> Language {
1840    Language::new(
1841        LanguageConfig {
1842            name: "Python".into(),
1843            matcher: LanguageMatcher {
1844                path_suffixes: vec!["py".to_string()],
1845                ..Default::default()
1846            },
1847            ..Default::default()
1848        },
1849        Some(tree_sitter_python::LANGUAGE.into()),
1850    )
1851}