@@ -6,7 +6,7 @@ use anyhow::{Result, Context, bail};
66use colored:: * ;
77use console:: Term ;
88use indicatif:: { ProgressBar , ProgressStyle } ;
9- use smart_diff_parser:: { Parser , LanguageDetector , Language } ;
9+ use smart_diff_parser:: { tree_sitter :: TreeSitterParser , Parser , LanguageDetector , Language } ;
1010use smart_diff_semantic:: { SemanticAnalyzer , SymbolTable } ;
1111use smart_diff_engine:: {
1212 DiffEngine , RefactoringDetector , RefactoringDetectionConfig ,
@@ -45,7 +45,7 @@ pub async fn run(cli: Cli) -> Result<()> {
4545
4646 if !cli. quiet {
4747 println ! ( "{}" , "Smart Code Diff - Structural Code Comparison" . bold( ) . blue( ) ) ;
48- println ! ( "{}" , "=" . repeat( 50 ) . dim ( ) ) ;
48+ println ! ( "{}" , "=" . repeat( 50 ) . dimmed ( ) ) ;
4949 }
5050
5151 // Validate inputs
@@ -86,8 +86,8 @@ pub async fn run(cli: Cli) -> Result<()> {
8686 pb. set_position ( 20 ) ;
8787 }
8888
89- let language_detector = LanguageDetector :: new ( ) ;
90- let mut parsers: HashMap < Language , Parser > = HashMap :: new ( ) ;
89+ let language_detector = LanguageDetector ;
90+ let mut parsers: HashMap < Language , TreeSitterParser > = HashMap :: new ( ) ;
9191 let mut comparison_results = Vec :: new ( ) ;
9292 let mut total_stats = ComparisonStats :: default ( ) ;
9393
@@ -245,7 +245,7 @@ async fn discover_directory_files(
245245 collect_files ( target_dir, recursive, include, exclude, & mut target_files) . await ?;
246246
247247 // Match files by relative path
248- for ( rel_path, source_file) in source_files {
248+ for ( rel_path, source_file) in & source_files {
249249 if let Some ( target_file) = target_files. get ( & rel_path) {
250250 file_pairs. push ( ( source_file, target_file. clone ( ) ) ) ;
251251 } else {
@@ -347,7 +347,7 @@ async fn process_file_pair(
347347 target_file : & Path ,
348348 language_override : & Option < crate :: cli:: Language > ,
349349 language_detector : & LanguageDetector ,
350- parsers : & mut HashMap < Language , Parser > ,
350+ parsers : & mut HashMap < Language , TreeSitterParser > ,
351351 threshold : f64 ,
352352 ignore_whitespace : bool ,
353353 ignore_case : bool ,
@@ -372,26 +372,29 @@ async fn process_file_pair(
372372 lang_override. to_parser_language ( )
373373 . context ( "Invalid language override" ) ?
374374 } else {
375- language_detector. detect_from_path ( source_file)
376- . or_else ( || language_detector. detect_from_content ( & source_content) )
377- . context ( "Could not detect programming language" ) ?
375+ let detected = LanguageDetector :: detect_from_path ( source_file) ;
376+ if detected != Language :: Unknown {
377+ detected
378+ } else {
379+ LanguageDetector :: detect_from_content ( & source_content)
380+ }
378381 } ;
379382
380383 debug ! ( "Detected language: {:?} for file: {}" , detected_language, source_file. display( ) ) ;
381384
382385 // Get or create parser for this language
383386 let parser = parsers. entry ( detected_language)
384- . or_insert_with ( || Parser :: new ( detected_language ) ) ;
387+ . or_insert_with ( || TreeSitterParser :: new ( ) . expect ( "Failed to create parser" ) ) ;
385388
386389 // Parse source and target files
387- let source_ast = parser. parse ( & source_content, Some ( source_file . to_string_lossy ( ) . to_string ( ) ) )
390+ let source_ast = parser. parse ( & source_content, detected_language )
388391 . with_context ( || format ! ( "Failed to parse source file: {}" , source_file. display( ) ) ) ?;
389392
390- let target_ast = parser. parse ( & target_content, Some ( target_file . to_string_lossy ( ) . to_string ( ) ) )
393+ let target_ast = parser. parse ( & target_content, detected_language )
391394 . with_context ( || format ! ( "Failed to parse target file: {}" , target_file. display( ) ) ) ?;
392395
393396 // Perform semantic analysis
394- let mut semantic_analyzer = SemanticAnalyzer :: new ( detected_language ) ;
397+ let mut semantic_analyzer = SemanticAnalyzer :: new ( ) ;
395398
396399 let source_symbols = semantic_analyzer. analyze ( & source_ast)
397400 . with_context ( || format ! ( "Failed to analyze source file: {}" , source_file. display( ) ) ) ?;
@@ -400,10 +403,10 @@ async fn process_file_pair(
400403 . with_context ( || format ! ( "Failed to analyze target file: {}" , target_file. display( ) ) ) ?;
401404
402405 // Initialize diff engine components
403- let mut diff_engine = DiffEngine :: new ( detected_language ) ;
406+ let mut diff_engine = DiffEngine :: new ( ) ;
404407
405408 // Configure similarity scorer
406- let mut similarity_scorer = SimilarityScorer :: new ( detected_language) ;
409+ let mut similarity_scorer = SimilarityScorer :: new ( detected_language, smart_diff_engine :: SimilarityScoringConfig :: default ( ) ) ;
407410 if ignore_whitespace {
408411 // Configure to ignore whitespace - would need to add this to SimilarityScorer
409412 debug ! ( "Ignoring whitespace in similarity calculation" ) ;
@@ -423,19 +426,21 @@ async fn process_file_pair(
423426
424427 // Configure cross-file tracker if enabled
425428 let cross_file_tracker = if track_moves {
426- Some ( CrossFileTracker :: new ( detected_language) )
429+ Some ( CrossFileTracker :: new ( detected_language, smart_diff_engine :: CrossFileTrackerConfig :: default ( ) ) )
427430 } else {
428431 None
429432 } ;
430433
431434 // Perform comparison
432435 let comparison_start = Instant :: now ( ) ;
433436
434- let diff_result = diff_engine. compare_files (
435- & source_ast,
436- & target_ast,
437- & source_symbols,
438- & target_symbols,
437+ // Extract functions from AST for comparison
438+ let source_functions = extract_functions_from_ast ( & source_ast. ast ) ;
439+ let target_functions = extract_functions_from_ast ( & target_ast. ast ) ;
440+
441+ let diff_result = diff_engine. compare_functions (
442+ & source_functions,
443+ & target_functions,
439444 ) . context ( "Failed to perform structural comparison" ) ?;
440445
441446 let comparison_time = comparison_start. elapsed ( ) ;
@@ -579,7 +584,7 @@ fn display_summary(
579584) -> Result < ( ) > {
580585 term. write_line ( "" ) ?;
581586 term. write_line ( & format ! ( "{}" , "Summary" . bold( ) . green( ) ) ) ?;
582- term. write_line ( & format ! ( "{}" , "-" . repeat( 20 ) . dim ( ) ) ) ?;
587+ term. write_line ( & format ! ( "{}" , "-" . repeat( 20 ) . dimmed ( ) ) ) ?;
583588
584589 term. write_line ( & format ! ( "Files compared: {}" , stats. files_compared. to_string( ) . bold( ) ) ) ?;
585590 term. write_line ( & format ! ( "Functions analyzed: {}" , stats. functions_compared. to_string( ) . bold( ) ) ) ?;
@@ -599,7 +604,7 @@ fn display_summary(
599604 if results. len ( ) > 1 {
600605 term. write_line ( "" ) ?;
601606 term. write_line ( & format ! ( "{}" , "Per-file Results" . bold( ) ) ) ?;
602- term. write_line ( & format ! ( "{}" , "-" . repeat( 20 ) . dim ( ) ) ) ?;
607+ term. write_line ( & format ! ( "{}" , "-" . repeat( 20 ) . dimmed ( ) ) ) ?;
603608
604609 for result in results {
605610 let file_name = result. source_file . file_name ( )
@@ -630,7 +635,7 @@ fn display_summary(
630635fn display_detailed_stats ( stats : & ComparisonStats , term : & Term ) -> Result < ( ) > {
631636 term. write_line ( "" ) ?;
632637 term. write_line ( & format ! ( "{}" , "Detailed Statistics" . bold( ) . cyan( ) ) ) ?;
633- term. write_line ( & format ! ( "{}" , "=" . repeat( 30 ) . dim ( ) ) ) ?;
638+ term. write_line ( & format ! ( "{}" , "=" . repeat( 30 ) . dimmed ( ) ) ) ?;
634639
635640 term. write_line ( & format ! ( "Parsing time: {}" , format_duration( stats. parsing_time) ) ) ?;
636641 term. write_line ( & format ! ( "Comparison time: {}" , format_duration( stats. comparison_time) ) ) ?;
0 commit comments