use std::fs;
use std::path::Path;
use std::process::Command;
use tempfile::TempDir;
fn main() {
println!("🚀 PMAT Context Analysis Demo");
println!("===============================");
println!("\n1. Testing TypeScript Context Analysis");
test_typescript_context();
println!("\n2. Testing JavaScript Context Analysis");
test_javascript_context();
println!("\n3. Testing WASM Context Analysis");
test_wasm_context();
println!("\n4. Testing Multi-Language Project");
test_multi_language_context();
println!("\n5. Testing Comprehensive Language Test Directory");
test_comprehensive_language_test();
println!("\n✅ Context Analysis Demo Completed!");
println!("All examples demonstrate the unified pmat context command");
println!("with enhanced naming and multi-language support.");
}
fn test_typescript_context() {
println!("Creating TypeScript test project...");
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let ts_content = r#"
// Enhanced TypeScript example with various function types
interface UserProfile {
id: number;
name: string;
getDisplayName(): string;
}
enum UserRole {
Admin,
User,
Guest
}
function calculateUserScore(profile: UserProfile, role: UserRole): number {
return profile.id * 100;
}
const processUserData = async (userData: any) => {
return await fetchUserDetails(userData.id);
};
class UserService {
private users: UserProfile[] = [];
createUser(profile: UserProfile): UserProfile {
this.users.push(profile);
return profile;
}
static validateUserRole(role: UserRole): boolean {
return Object.values(UserRole).includes(role);
}
async fetchUserById(id: number): Promise<UserProfile | null> {
return this.users.find(u => u.id === id) || null;
}
}
const userUtils = {
formatUserName(user: UserProfile): string {
return `${user.name} (${user.id})`;
},
isValidUser: (user: UserProfile) => user.id > 0
};
async function fetchUserDetails(id: number): Promise<any> {
return { id, name: `User ${id}` };
}
"#;
let ts_file = temp_dir.path().join("user_service.ts");
fs::write(&ts_file, ts_content).expect("Failed to write TypeScript file");
println!(
"Running: cargo run --bin pmat -- context --project-path {} --format llm-optimized",
temp_dir.path().display()
);
let output = Command::new("cargo")
.args([
"run",
"--bin",
"pmat",
"--",
"context",
"--project-path",
temp_dir.path().to_str().unwrap(),
"--format",
"llm-optimized",
])
.output()
.expect("Failed to run cargo command");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("✅ TypeScript analysis successful!");
if let Some(functions_line) = stdout.lines().find(|line| line.contains("Functions:")) {
println!(" {}", functions_line);
}
if let Some(files_line) = stdout.lines().find(|line| line.contains("Files:")) {
println!(" {}", files_line);
}
let function_count = extract_function_count(&stdout);
if function_count >= 7 {
println!(
" 🎯 Successfully detected {} TypeScript functions!",
function_count
);
println!(" Expected: calculateUserScore, processUserData, createUser, validateUserRole, fetchUserById, formatUserName, fetchUserDetails");
} else {
println!(
" ⚠️ Only detected {} functions, expected at least 7",
function_count
);
}
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
println!("❌ TypeScript analysis failed: {}", stderr);
}
}
fn test_javascript_context() {
println!("Creating JavaScript test project...");
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let js_content = r#"
// Enhanced JavaScript example with various function patterns
function calculateTotalPrice(items, taxRate) {
return items.reduce((total, item) => total + item.price, 0) * (1 + taxRate);
}
const processOrderData = async (orderData) => {
const processedData = await validateOrder(orderData);
return formatOrderResponse(processedData);
};
class ShoppingCart {
constructor() {
this.items = [];
this.totalValue = 0;
}
addItem(item) {
this.items.push(item);
this.updateTotal();
return this.items.length;
}
removeItem(itemId) {
const index = this.items.findIndex(item => item.id === itemId);
if (index > -1) {
this.items.splice(index, 1);
this.updateTotal();
}
}
updateTotal() {
this.totalValue = this.items.reduce((sum, item) => sum + item.price, 0);
}
static createEmptyCart() {
return new ShoppingCart();
}
}
const orderUtils = {
formatOrderId: (id) => `ORD-${id.toString().padStart(6, '0')}`,
validateOrderItems(items) {
return items.every(item => item.price > 0 && item.quantity > 0);
},
calculateShipping: function(weight, destination) {
return weight * 2.5 + (destination === 'international' ? 15 : 5);
}
};
async function validateOrder(orderData) {
// Validation logic
return orderData;
}
function formatOrderResponse(processedOrder) {
return {
id: orderUtils.formatOrderId(processedOrder.id),
status: 'processed',
items: processedOrder.items
};
}
"#;
let js_file = temp_dir.path().join("shopping_cart.js");
fs::write(&js_file, js_content).expect("Failed to write JavaScript file");
println!(
"Running: cargo run --bin pmat -- context --project-path {} --format llm-optimized",
temp_dir.path().display()
);
let output = Command::new("cargo")
.args([
"run",
"--bin",
"pmat",
"--",
"context",
"--project-path",
temp_dir.path().to_str().unwrap(),
"--format",
"llm-optimized",
])
.output()
.expect("Failed to run cargo command");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("✅ JavaScript analysis successful!");
if let Some(functions_line) = stdout.lines().find(|line| line.contains("Functions:")) {
println!(" {}", functions_line);
}
let function_count = extract_function_count(&stdout);
if function_count >= 10 {
println!(
" 🎯 Successfully detected {} JavaScript functions!",
function_count
);
println!(" Expected: calculateTotalPrice, processOrderData, addItem, removeItem, updateTotal, createEmptyCart, formatOrderId, validateOrderItems, calculateShipping, validateOrder, formatOrderResponse");
} else {
println!(
" ⚠️ Only detected {} functions, expected at least 10",
function_count
);
}
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
println!("❌ JavaScript analysis failed: {}", stderr);
}
}
fn test_wasm_context() {
println!("Creating WASM test project...");
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let wasm_content = r#"
(module
;; Import memory from host environment
(import "env" "memory" (memory 1))
;; Mathematical operations
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
(func $multiply (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.mul
)
;; Recursive fibonacci implementation
(func $fibonacci (param $n i32) (result i32)
(local $temp i32)
local.get $n
i32.const 2
i32.lt_s
if (result i32)
local.get $n
else
local.get $n
i32.const 1
i32.sub
call $fibonacci
local.get $n
i32.const 2
i32.sub
call $fibonacci
i32.add
end
)
;; Factorial calculation
(func $factorial (param $n i32) (result i32)
(local $result i32)
(local $counter i32)
i32.const 1
local.set $result
i32.const 1
local.set $counter
loop $factorial_loop
local.get $counter
local.get $n
i32.gt_s
if
br $factorial_loop
end
local.get $result
local.get $counter
i32.mul
local.set $result
local.get $counter
i32.const 1
i32.add
local.set $counter
br $factorial_loop
end
local.get $result
)
;; Power function
(func $power (param $base i32) (param $exp i32) (result i32)
(local $result i32)
(local $counter i32)
i32.const 1
local.set $result
i32.const 0
local.set $counter
loop $power_loop
local.get $counter
local.get $exp
i32.ge_s
if
br $power_loop
end
local.get $result
local.get $base
i32.mul
local.set $result
local.get $counter
i32.const 1
i32.add
local.set $counter
br $power_loop
end
local.get $result
)
;; Export all functions for use
(export "add" (func $add))
(export "multiply" (func $multiply))
(export "fibonacci" (func $fibonacci))
(export "factorial" (func $factorial))
(export "power" (func $power))
)
"#;
let wasm_file = temp_dir.path().join("math_operations.wat");
fs::write(&wasm_file, wasm_content).expect("Failed to write WASM file");
println!(
"Running: cargo run --bin pmat -- context --project-path {} --format llm-optimized",
temp_dir.path().display()
);
let output = Command::new("cargo")
.args([
"run",
"--bin",
"pmat",
"--",
"context",
"--project-path",
temp_dir.path().to_str().unwrap(),
"--format",
"llm-optimized",
])
.output()
.expect("Failed to run cargo command");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("✅ WASM analysis successful!");
if let Some(functions_line) = stdout.lines().find(|line| line.contains("Functions:")) {
println!(" {}", functions_line);
}
let function_count = extract_function_count(&stdout);
if function_count >= 5 {
println!(
" 🎯 Successfully detected {} WASM functions!",
function_count
);
println!(" Expected: add, multiply, fibonacci, factorial, power");
} else {
println!(
" ⚠️ Only detected {} functions, expected at least 5",
function_count
);
}
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
println!("❌ WASM analysis failed: {}", stderr);
}
}
fn test_multi_language_context() {
println!("Creating multi-language test project...");
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let rust_content = r#"
pub fn calculate_hash(input: &str) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
input.hash(&mut hasher);
hasher.finish()
}
pub async fn fetch_data_async(url: &str) -> Result<String, Box<dyn std::error::Error>> {
// Simulated async operation
Ok(format!("Data from {}", url))
}
pub struct DataProcessor {
cache: std::collections::HashMap<String, String>,
}
impl DataProcessor {
pub fn new() -> Self {
Self {
cache: std::collections::HashMap::new(),
}
}
pub fn process_data(&mut self, key: &str, data: String) -> String {
self.cache.insert(key.to_string(), data.clone());
data.to_uppercase()
}
}
"#;
let rust_file = temp_dir.path().join("processor.rs");
fs::write(&rust_file, rust_content).expect("Failed to write Rust file");
let python_content = r#"
def calculate_fibonacci(n):
"""Calculate fibonacci number using dynamic programming."""
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
class DataAnalyzer:
def __init__(self):
self.data = []
def add_data_point(self, value):
"""Add a data point to the analyzer."""
self.data.append(value)
def calculate_average(self):
"""Calculate the average of all data points."""
if not self.data:
return 0
return sum(self.data) / len(self.data)
def find_max_value(self):
"""Find the maximum value in the dataset."""
return max(self.data) if self.data else None
async def process_async_data(data_list):
"""Process data asynchronously."""
import asyncio
await asyncio.sleep(0.1) # Simulated async work
return [item * 2 for item in data_list]
def validate_email(email):
"""Validate email format using regex."""
import re
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
"#;
let python_file = temp_dir.path().join("analyzer.py");
fs::write(&python_file, python_content).expect("Failed to write Python file");
let simple_ts_content = r#"
export function formatCurrency(amount: number, currency: string = 'USD'): string {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency
}).format(amount);
}
export const debounce = <T extends (...args: any[]) => void>(
func: T,
delay: number
): ((...args: Parameters<T>) => void) => {
let timeoutId: NodeJS.Timeout;
return (...args: Parameters<T>) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func(...args), delay);
};
};
"#;
let simple_ts_file = temp_dir.path().join("utils.ts");
fs::write(&simple_ts_file, simple_ts_content).expect("Failed to write simple TypeScript file");
println!(
"Running: cargo run --bin pmat -- context --project-path {} --format llm-optimized",
temp_dir.path().display()
);
let output = Command::new("cargo")
.args([
"run",
"--bin",
"pmat",
"--",
"context",
"--project-path",
temp_dir.path().to_str().unwrap(),
"--format",
"llm-optimized",
])
.output()
.expect("Failed to run cargo command");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("✅ Multi-language analysis successful!");
if let Some(language_line) = stdout
.lines()
.find(|line| line.starts_with("Project:") && line.contains("("))
{
println!(" {}", language_line);
}
if let Some(files_line) = stdout.lines().find(|line| line.contains("Files:")) {
println!(" {}", files_line);
}
if let Some(functions_line) = stdout.lines().find(|line| line.contains("Functions:")) {
println!(" {}", functions_line);
}
let function_count = extract_function_count(&stdout);
if function_count >= 10 {
println!(
" 🎯 Successfully detected {} functions across multiple languages!",
function_count
);
println!(" Expected functions from Rust, Python, and TypeScript files");
} else {
println!(
" ⚠️ Only detected {} functions, expected at least 10",
function_count
);
}
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
println!("❌ Multi-language analysis failed: {}", stderr);
}
}
fn test_comprehensive_language_test() {
println!("Testing comprehensive language test directory...");
let test_dir = Path::new("comprehensive_language_test");
if !test_dir.exists() {
println!("⚠️ Comprehensive language test directory not found, skipping...");
return;
}
println!("Running: cargo run --bin pmat -- context --project-path comprehensive_language_test --format llm-optimized");
let output = Command::new("cargo")
.args([
"run",
"--bin",
"pmat",
"--",
"context",
"--project-path",
"comprehensive_language_test",
"--format",
"llm-optimized",
])
.output()
.expect("Failed to run cargo command");
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
println!("✅ Comprehensive language test analysis successful!");
if let Some(language_line) = stdout
.lines()
.find(|line| line.starts_with("Project:") && line.contains("("))
{
println!(" {}", language_line);
}
if let Some(files_line) = stdout.lines().find(|line| line.contains("Files:")) {
println!(" {}", files_line);
}
if let Some(functions_line) = stdout.lines().find(|line| line.contains("Functions:")) {
println!(" {}", functions_line);
}
let function_count = extract_function_count(&stdout);
println!(
" 🎯 Detected {} functions in comprehensive test suite",
function_count
);
if function_count >= 50 {
println!(
" 🚀 Excellent! High function count indicates comprehensive language detection"
);
} else if function_count >= 20 {
println!(" ✅ Good function detection across multiple languages");
} else {
println!(" ⚠️ Lower than expected function count - may indicate detection issues");
}
} else {
let stderr = String::from_utf8_lossy(&output.stderr);
println!("❌ Comprehensive language test analysis failed: {}", stderr);
}
}
fn extract_function_count(output: &str) -> usize {
output
.lines()
.find(|line| line.contains("Functions:"))
.and_then(|line| line.split("Functions:").nth(1))
.and_then(|part| part.trim().parse().ok())
.unwrap_or(0)
}