nocturne 0.0.1

Code analyzer
Documentation
use judge::semantic::SemanticRustJudge;
use judge::{Judge, Position, SemanticJudge};

fn main() {
    println!("Semantic Analysis with rust-analyzer\n");

    let source = r#"
struct Person {
    name: String,
    age: u32,
}

impl Person {
    fn new(name: String, age: u32) -> Self {
        Self { name, age }
    }

    fn greet(&self) {
        println!("Hello, I'm {}!", self.name);
    }
}

fn main() {
    let person = Person::new("Alice".to_string(), 30);
    person.greet();
}
"#;

    let judge = SemanticRustJudge::new();

    // 1. Basic symbol extraction (syntax level)
    println!("1. Symbol Extraction (Syntax Level):");
    if let Ok(symbols) = judge.symbols(source) {
        for symbol in &symbols {
            println!("   {:?}: {}", symbol.kind, symbol.name);
            if let Some(detail) = &symbol.detail {
                println!("      {}", detail);
            }
        }
    }

    // 2. Hover information (semantic level)
    println!("\n2. Hover Information (Semantic Level):");

    // Hover over "Person" struct
    let pos = Position { line: 1, column: 7 }; // "Person" in struct definition
    match judge.hover(source, pos) {
        Ok(Some(hover)) => {
            println!("   Hover at {}:{}", pos.line, pos.column);
            println!("   {}", hover.contents);
        }
        Ok(None) => println!("   No hover info at {}:{}", pos.line, pos.column),
        Err(e) => println!("   Error: {}", e),
    }

    // 3. Go to definition
    println!("\n3. Go to Definition:");

    // Click on "Person" in Person::new
    let pos = Position {
        line: 17,
        column: 18,
    }; // "Person" in Person::new call
    match judge.goto_definition(source, pos) {
        Ok(Some(range)) => {
            println!(
                "   Definition found at {}:{} - {}:{}",
                range.start.line, range.start.column, range.end.line, range.end.column
            );
        }
        Ok(None) => println!("   No definition found"),
        Err(e) => println!("   Error: {}", e),
    }

    // 4. Find all references
    println!("\n4. Find All References:");

    // Find all references to "Person"
    let pos = Position { line: 1, column: 7 }; // "Person" struct name
    match judge.find_references(source, pos) {
        Ok(refs) => {
            println!("   Found {} references:", refs.len());
            for (i, ref_item) in refs.iter().enumerate() {
                let kind = if ref_item.is_definition { "def" } else { "ref" };
                println!(
                    "   [{}] {} at {}:{} - {}:{}",
                    i + 1,
                    kind,
                    ref_item.range.start.line,
                    ref_item.range.start.column,
                    ref_item.range.end.line,
                    ref_item.range.end.column
                );
            }
        }
        Err(e) => println!("   Error: {}", e),
    }

    // 5. Type inference
    println!("\n5. Type Inference:");

    // Get type of "person" variable
    let pos = Position {
        line: 17,
        column: 9,
    }; // "person" variable
    match judge.infer_type(source, pos) {
        Ok(Some(type_str)) => {
            println!("   Type at {}:{}: {}", pos.line, pos.column, type_str);
        }
        Ok(None) => println!("   No type info at {}:{}", pos.line, pos.column),
        Err(e) => println!("   Error: {}", e),
    }

    // 6. Smart completions (note: requires full workspace setup, may fall back to basic completions)
    println!("\n6. Completions:");
    println!("   Note: Semantic completions require full workspace/crate data setup.");
    println!("   Basic keyword completions are always available:");

    let pos = Position { line: 1, column: 0 };
    match judge.completions(source, pos) {
        Ok(completions) => {
            println!("   Available completions (showing first 5):");
            for item in completions.iter().take(5) {
                println!("   - {} ({:?})", item.label, item.kind);
                if let Some(detail) = &item.detail {
                    println!("     {}", detail);
                }
            }
        }
        Err(e) => println!("   Error: {}", e),
    }

    // 7. Signature help
    println!("\n7. Signature Help:");

    // Signature help inside function call
    let sig_source = r#"
fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn main() {
    add(1, 2);
}
"#;

    let pos = Position { line: 6, column: 8 }; // inside add() call
    match judge.signature_help(sig_source, pos) {
        Ok(Some(sig)) => {
            println!("   Signature: {}", sig.label);
            if let Some(doc) = &sig.documentation {
                println!("   Doc: {}", doc);
            }
            if let Some(active) = sig.active_parameter {
                println!("   Active parameter: {}", active);
            }
        }
        Ok(None) => println!("   No signature help available"),
        Err(e) => println!("   Error: {}", e),
    }

    println!("\nSemantic Analysis Complete");
}