Skip to content

Conversation

@KJ7LNW
Copy link
Contributor

@KJ7LNW KJ7LNW commented Apr 6, 2025

Context

This PR enhances the Rust tree-sitter parser to support a comprehensive set of Rust language structures, significantly improving code definition extraction capabilities.

Implementation

  • Added support for additional Rust language structures:

    • Enum definitions
    • Trait definitions
    • Impl trait for struct
    • Generic structs with lifetime parameters
    • Macro definitions
    • Module definitions
    • Union types
    • Closures
    • Match expressions
    • Where clauses
    • Async functions
    • Impl blocks with generic parameters
    • Complex trait bounds
  • Updated tests to verify capture of these structures

  • Modified debug helper to use environment variables for easier debugging

How to Test

  1. Run the Rust tree-sitter tests:

Found 1 test suites
......
Ran 6 tests in 0.263 s
6 passing 0 failing 0 pending

  1. To see debug output, set the DEBUG environment variable:

Found 1 test suites
console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

console.debug
content:

// Basic struct definition
struct Point {
    x: f64,
    y: f64,
}

// Struct with implementation (methods)
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    // Method definition
    fn area(&self) -> u32 {
        self.width * self.height
    }

    // Another method
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }

    // Associated function (not a method, but still part of impl)
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

// A standalone function
fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
    let dx = p2.x - p1.x;
    let dy = p2.y - p1.y;
    (dx * dx + dy * dy).sqrt()
}

// A more complex struct
struct Vehicle {
    make: String,
    model: String,
    year: u32,
}

impl Vehicle {
    // Constructor-like method
    fn new(make: String, model: String, year: u32) -> Vehicle {
        Vehicle {
            make,
            model,
            year,
        }
    }

    // Regular method
    fn description(&self) -> String {
        format!("{} {} ({})", self.make, self.model, self.year)
    }
}

// Another standalone function
fn process_data(input: &str) -> String {
    format!("Processed: {}", input)
}

// More complex Rust structures for advanced testing
enum Status {
    Active,
    Inactive,
    Pending(String),
    Error { code: i32, message: String },
}

trait Drawable {
    fn draw(&self);
    fn get_dimensions(&self) -> (u32, u32);
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("Drawing rectangle: {}x{}", self.width, self.height);
    }
    
    fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

// Generic struct with lifetime parameters
struct Container<'a, T> {
    data: &'a T,
    count: usize,
}

impl<'a, T> Container<'a, T> {
    fn new(data: &'a T) -> Container<'a, T> {
        Container {
            data,
            count: 1,
        }
    }
}

// Macro definition
macro_rules! say_hello {
    // Match a single name
    ($name:expr) => {
        println!("Hello, {}!", $name);
    };
    // Match multiple names
    ($($name:expr),*) => {
        $(
            println!("Hello, {}!", $name);
        )*
    };
}

// Module definition
mod math {
    // Constants
    pub const PI: f64 = 3.14159;
    
    // Static variables
    pub static VERSION: &str = "1.0.0";
    
    // Type alias
    pub type Number = f64;
    
    // Functions within modules
    pub fn add(a: Number, b: Number) -> Number {
        a + b
    }
    
    pub fn subtract(a: Number, b: Number) -> Number {
        a - b
    }
}

// Union type
union IntOrFloat {
    int_value: i32,
    float_value: f32,
}

// Trait with associated types
trait Iterator {
    // Associated type
    type Item;
    
    // Method using associated type
    fn next(&mut self) -> Option<Self::Item>;
    
    // Default implementation
    fn count(self) -> usize where Self: Sized {
        let mut count = 0;
        while let Some(_) = self.next() {
            count += 1;
        }
        count
    }
}

// Advanced Rust language features for testing

// 1. Closures: Multi-line anonymous functions with captured environments
fn use_closures() {
    let captured_value = 42;
    
    // Simple closure
    let simple_closure = || {
        println!("Captured value: {}", captured_value);
    };
    
    // Closure with parameters
    let add_closure = |a: i32, b: i32| -> i32 {
        let sum = a + b + captured_value;
        println!("Sum with captured value: {}", sum);
        sum
    };
    
    // Using closures
    simple_closure();
    let result = add_closure(10, 20);
}

// 2. Match Expressions: Complex pattern matching constructs
fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
    match value {
        Some(Ok(vec)) if vec.len() > 5 => {
            println!("Got a vector with more than 5 elements");
            for item in vec {
                println!("Item: {}", item);
            }
        },
        Some(Ok(vec)) => {
            println!("Got a vector with {} elements", vec.len());
        },
        Some(Err(e)) => {
            println!("Got an error: {}", e);
        },
        None => {
            println!("Got nothing");
        }
    }
}

// 3. Where Clauses: Type constraints on generic parameters
fn print_sorted<T>(collection: &[T])
where
    T: std::fmt::Debug + Ord + Clone,
{
    let mut sorted = collection.to_vec();
    sorted.sort();
    println!("Sorted collection: {:?}", sorted);
}

// 4. Attribute Macros: Annotations that modify behavior
#[derive(Debug, Clone, PartialEq)]
struct AttributeExample {
    field1: String,
    field2: i32,
}

#[cfg(test)]
mod test_module {
    #[test]
    fn test_example() {
        assert_eq!(2 + 2, 4);
    }
}

// 5. Procedural Macros (simulated, as they require separate crates)
// This is a placeholder to represent a proc macro
// In real code, this would be in a separate crate with #[proc_macro]
fn custom_derive_macro() {
    // Implementation would generate code at compile time
}

// 6. Async Functions and Blocks: Asynchronous code constructs
async fn fetch_data(url: &str) -> Result<String, String> {
    // Simulated async operation
    println!("Fetching data from {}", url);
    
    // Async block
    let result = async {
        // Simulated async work
        Ok("Response data".to_string())
    }.await;
    
    result
}

// 7. Impl Blocks with Generic Parameters: Implementation with complex type parameters
struct GenericContainer<T, U> {
    first: T,
    second: U,
}

impl<T, U> GenericContainer<T, U>
where
    T: std::fmt::Display,
    U: std::fmt::Debug,
{
    fn new(first: T, second: U) -> Self {
        GenericContainer { first, second }
    }
    
    fn display(&self) {
        println!("First: {}, Second: {:?}", self.first, self.second);
    }
}

// 8. Complex Trait Bounds: Trait bounds using + operator or where clauses
trait Processor<T> {
    fn process(&self, item: T) -> T;
}

fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>
where
    P: Processor<T> + Clone,
    T: Clone + std::fmt::Debug + 'static,
{
    items.into_iter()
         .map(|item| processor.process(item))
         .collect()
}


Result:
# file.rs
3--6 | struct Point {
2--289 | // Basic struct definition
9--12 | struct Rectangle {
14--32 | impl Rectangle {
26--31 |     fn square(size: u32) -> Rectangle {
35--39 | fn calculate_distance(p1: &Point, p2: &Point) -> f64 {
42--46 | struct Vehicle {
48--62 | impl Vehicle {
50--56 |     fn new(make: String, model: String, year: u32) -> Vehicle {
70--75 | enum Status {
77--80 | trait Drawable {
82--90 | impl Drawable for Rectangle {
93--96 | struct Container<'a, T> {
98--105 | impl<'a, T> Container<'a, T> {
99--104 |     fn new(data: &'a T) -> Container<'a, T> {
108--119 | macro_rules! say_hello {
122--140 | mod math {
143--146 | union IntOrFloat {
149--164 | trait Iterator {
157--163 |     fn count(self) -> usize where Self: Sized {
169--187 | fn use_closures() {
178--182 |     let add_closure = |a: i32, b: i32| -> i32 {
190--208 | fn complex_matching(value: Option<Result<Vec<i32>, String>>) {
191--207 |     match value {
211--218 | fn print_sorted<T>(collection: &[T])
222--225 | struct AttributeExample {
228--233 | mod test_module {
243--254 | async fn fetch_data(url: &str) -> Result<String, String> {
257--260 | struct GenericContainer<T, U> {
262--274 | impl<T, U> GenericContainer<T, U>
266--274 | {
281--289 | fn process_items<T, P>(processor: P, items: Vec<T>) -> Vec<T>

  at debugLog (src/services/tree-sitter/__tests__/helpers.ts:14:11)

......
Ran 6 tests in 0.247 s
6 passing 0 failing 0 pending

Get in Touch

Discord: KJ7LNW


Important

Enhances Rust tree-sitter parser to support advanced Rust language structures and updates tests for comprehensive coverage.

  • Behavior:
    • Enhances Rust tree-sitter parser to support additional language structures: enums, traits, impl traits, generic structs, macros, modules, unions, closures, match expressions, where clauses, async functions, impl blocks with generics, and complex trait bounds.
    • Updates rust.ts query definitions to capture these structures.
  • Testing:
    • Adds parseSourceCodeDefinitions.rust.test.ts to test parsing of new Rust structures.
    • Verifies capture of structs, functions, enums, traits, macros, modules, unions, closures, match expressions, and more.
  • Misc:
    • Modifies helpers.ts to use environment variables for debug logging.

This description was created by Ellipsis for d1f41ed. It will automatically update as commits are pushed.

Eric Wheeler added 2 commits April 5, 2025 16:21
Add test suite for Rust language support in Tree-sitter:
- Verify parsing of struct definitions
- Verify parsing of method definitions within impl blocks
- Verify parsing of standalone function definitions
- Add tests for complex Rust structures
- Include skipped debug test for future diagnostics

These tests confirm the existing Rust support in Tree-sitter is working correctly and provide a foundation for future enhancements to the Rust parser.

Signed-off-by: Eric Wheeler <[email protected]>
- Add support for additional Rust language structures:
  - Enum definitions
  - Trait definitions
  - Impl trait for struct
  - Generic structs with lifetime parameters
  - Macro definitions
  - Module definitions
  - Union types
  - Closures
  - Match expressions
  - Where clauses
  - Async functions
  - Impl blocks with generic parameters
  - Complex trait bounds

- Update tests to verify capture of these structures
- Modify debug helper to use environment variables

Signed-off-by: Eric Wheeler <[email protected]>
@changeset-bot
Copy link

changeset-bot bot commented Apr 6, 2025

⚠️ No Changeset found

Latest commit: d1f41ed

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Apr 6, 2025
@dosubot dosubot bot added the enhancement New feature or request label Apr 6, 2025
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Apr 6, 2025
@mrubens mrubens merged commit 5fb9af4 into RooCodeInc:main Apr 6, 2025
19 checks passed
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Apr 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants