5050use super :: Entry ;
5151use super :: { ConfigurablePathFormatter , PathFormatter } ;
5252use crate :: config;
53- use crate :: semantic:: interpreters:: is_binary_file;
5453use crate :: semantic:: { ArgumentKind , Arguments , Command , CompilerCommand , CompilerPass , PassEffect } ;
5554use log:: warn;
5655use std:: borrow:: Cow ;
@@ -101,8 +100,10 @@ impl CommandConverter {
101100 // Create output file if needed
102101 let output_file = self . create_output_file ( & formatted_directory, & cmd. arguments ) ;
103102
104- // Create one entry per source argument
105- Self :: find_arguments_by_kind ( cmd, ArgumentKind :: Source )
103+ // Create one entry per source argument (only non-binary source files)
104+ cmd. arguments
105+ . iter ( )
106+ . filter ( |arg| matches ! ( arg. kind( ) , ArgumentKind :: Source { binary: false } ) )
106107 . filter_map ( |source_arg| {
107108 // Get and format source file
108109 let path_updater: & dyn Fn ( & Path ) -> Cow < Path > = & |path : & Path | Cow :: Borrowed ( path) ;
@@ -202,7 +203,7 @@ impl CommandConverter {
202203 // Add all non-source arguments, while handling source file placement
203204 for arg in & cmd. arguments {
204205 // Skip this specific source argument (using pointer equality)
205- if matches ! ( arg. kind( ) , ArgumentKind :: Source ) && !std:: ptr:: eq ( arg. as_ref ( ) , source_arg) {
206+ if matches ! ( arg. kind( ) , ArgumentKind :: Source { .. } ) && !std:: ptr:: eq ( arg. as_ref ( ) , source_arg) {
206207 continue ;
207208 }
208209
@@ -221,7 +222,7 @@ impl CommandConverter {
221222
222223 // For file-type arguments, we need to format the paths
223224 match arg. kind ( ) {
224- ArgumentKind :: Source | ArgumentKind :: Output => {
225+ ArgumentKind :: Source { .. } | ArgumentKind :: Output => {
225226 // These might contain file paths that need formatting
226227 let formatted_args = original_args
227228 . into_iter ( )
@@ -264,11 +265,19 @@ impl CommandConverter {
264265 /// Returns arguments of a specific kind from the command.
265266 ///
266267 /// This method filters arguments by their kind and returns their values as strings.
268+ /// For `ArgumentKind::Source`, this matches any source regardless of the `binary` flag.
267269 fn find_arguments_by_kind (
268270 cmd : & CompilerCommand ,
269271 kind : ArgumentKind ,
270272 ) -> impl Iterator < Item = & Box < dyn Arguments > > {
271- cmd. arguments . iter ( ) . filter ( move |arg| arg. kind ( ) == kind)
273+ cmd. arguments . iter ( ) . filter ( move |arg| {
274+ match ( arg. kind ( ) , kind) {
275+ // For Source, match any source regardless of binary flag
276+ ( ArgumentKind :: Source { .. } , ArgumentKind :: Source { .. } ) => true ,
277+ // For other kinds, use exact equality
278+ ( a, b) => a == b,
279+ }
280+ } )
272281 }
273282
274283 /// Determines if we should skip generating compilation database entries for a command.
@@ -289,9 +298,9 @@ impl CommandConverter {
289298 return true ;
290299 }
291300
292- // Find all source arguments
293- let source_arguments =
294- Self :: find_arguments_by_kind ( cmd , ArgumentKind :: Source ) . collect :: < Vec < & Box < dyn Arguments > > > ( ) ;
301+ // Find all source arguments (using binary: false as a placeholder, find_arguments_by_kind matches any source)
302+ let source_arguments = Self :: find_arguments_by_kind ( cmd , ArgumentKind :: Source { binary : false } )
303+ . collect :: < Vec < & Box < dyn Arguments > > > ( ) ;
295304
296305 // If no source files found, skip entry generation
297306 if source_arguments. is_empty ( ) {
@@ -333,9 +342,8 @@ impl CommandConverter {
333342 ///
334343 /// This typically happens when linking pre-compiled object files or libraries.
335344 ///
336- /// Note: Arguments with `ArgumentKind::Source` have already been validated by
337- /// `looks_like_a_source_file()` during semantic analysis, but we still need to
338- /// exclude object files (.o, .a, etc.) which may be misclassified in tests.
345+ /// The `binary` flag on `ArgumentKind::Source` is set during semantic analysis
346+ /// by the interpreter, so we can simply check it here.
339347 fn is_linking_only ( & self , cmd : & CompilerCommand ) -> bool {
340348 // Check if the command has a flag that stops before linking (-c or -S)
341349 let stops_before_linking = cmd. arguments . iter ( ) . any ( |arg| {
@@ -351,17 +359,10 @@ impl CommandConverter {
351359 return false ;
352360 }
353361
354- // Check if there are any compilable source files (not object/library files)
362+ // Check if there are any compilable source files (not binary files)
363+ // The binary flag is set by the interpreter during semantic analysis
355364 let has_compilable_sources =
356- Self :: find_arguments_by_kind ( cmd, ArgumentKind :: Source ) . any ( |source_arg| {
357- let path_updater: & dyn Fn ( & Path ) -> Cow < Path > = & |path : & Path | Cow :: Borrowed ( path) ;
358- if let Some ( file_path) = source_arg. as_file ( path_updater) {
359- // Check if this is a compilable source file (not a binary file)
360- !is_binary_file ( & file_path)
361- } else {
362- false
363- }
364- } ) ;
365+ cmd. arguments . iter ( ) . any ( |arg| matches ! ( arg. kind( ) , ArgumentKind :: Source { binary: false } ) ) ;
365366
366367 // If no -c/-S flag and no compilable sources, it's linking-only
367368 !has_compilable_sources
@@ -385,7 +386,7 @@ mod tests {
385386 ( ArgumentKind :: Compiler , vec![ "/usr/bin/gcc" ] ) ,
386387 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
387388 ( ArgumentKind :: Other ( PassEffect :: None ) , vec![ "-Wall" ] ) ,
388- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
389+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
389390 ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
390391 ] ,
391392 ) ) ;
@@ -411,8 +412,8 @@ mod tests {
411412 vec ! [
412413 ( ArgumentKind :: Compiler , vec![ "/usr/bin/g++" ] ) ,
413414 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
414- ( ArgumentKind :: Source , vec![ "file1.cpp" ] ) ,
415- ( ArgumentKind :: Source , vec![ "file2.cpp" ] ) ,
415+ ( ArgumentKind :: Source { binary : false } , vec![ "file1.cpp" ] ) ,
416+ ( ArgumentKind :: Source { binary : false } , vec![ "file2.cpp" ] ) ,
416417 ] ,
417418 ) ) ;
418419
@@ -451,7 +452,7 @@ mod tests {
451452 vec ! [
452453 ( ArgumentKind :: Compiler , vec![ "/usr/bin/gcc" ] ) ,
453454 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
454- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
455+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
455456 ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
456457 ] ,
457458 ) ) ;
@@ -475,7 +476,7 @@ mod tests {
475476 vec ! [
476477 ( ArgumentKind :: Compiler , vec![ "/usr/bin/gcc" ] ) ,
477478 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
478- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
479+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
479480 ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
480481 ] ,
481482 ) ) ;
@@ -509,7 +510,7 @@ mod tests {
509510 "/usr/bin/gcc" ,
510511 vec ! [
511512 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
512- ( ArgumentKind :: Source , vec![ "test.c" ] ) ,
513+ ( ArgumentKind :: Source { binary : false } , vec![ "test.c" ] ) ,
513514 ] ,
514515 ) ;
515516 let command = Command :: Compiler ( compiler_cmd) ;
@@ -539,7 +540,10 @@ mod tests {
539540 let compiler_cmd = CompilerCommand :: from_strings (
540541 "/original/dir" ,
541542 "/usr/bin/gcc" ,
542- vec ! [ ( ArgumentKind :: Source , vec![ "main.c" ] ) , ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ] ,
543+ vec ! [
544+ ( ArgumentKind :: Source { binary: false } , vec![ "main.c" ] ) ,
545+ ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
546+ ] ,
543547 ) ;
544548 let command = Command :: Compiler ( compiler_cmd) ;
545549
@@ -564,7 +568,7 @@ mod tests {
564568 let compiler_cmd = CompilerCommand :: from_strings (
565569 "/nonexistent/dir" ,
566570 "/usr/bin/gcc" ,
567- vec ! [ ( ArgumentKind :: Source , vec![ "main.c" ] ) ] ,
571+ vec ! [ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ] ,
568572 ) ;
569573 let command = Command :: Compiler ( compiler_cmd) ;
570574
@@ -590,7 +594,7 @@ mod tests {
590594 let compiler_cmd = CompilerCommand :: from_strings (
591595 "/home/user" ,
592596 "/usr/bin/gcc" ,
593- vec ! [ ( ArgumentKind :: Source , vec![ "nonexistent.c" ] ) ] ,
597+ vec ! [ ( ArgumentKind :: Source { binary : false } , vec![ "nonexistent.c" ] ) ] ,
594598 ) ;
595599 let command = Command :: Compiler ( compiler_cmd) ;
596600
@@ -633,7 +637,10 @@ mod tests {
633637 let compiler_cmd = CompilerCommand :: from_strings (
634638 "/home/user" ,
635639 "/usr/bin/gcc" ,
636- vec ! [ ( ArgumentKind :: Source , vec![ "main.c" ] ) , ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ] ,
640+ vec ! [
641+ ( ArgumentKind :: Source { binary: false } , vec![ "main.c" ] ) ,
642+ ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
643+ ] ,
637644 ) ;
638645 let command = Command :: Compiler ( compiler_cmd) ;
639646
@@ -655,7 +662,7 @@ mod tests {
655662 "gcc" ,
656663 vec ! [
657664 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Preprocessing ) ) , vec![ "-E" ] ) ,
658- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
665+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
659666 ] ,
660667 ) ;
661668 let command = Command :: Compiler ( compiler_cmd) ;
@@ -674,7 +681,8 @@ mod tests {
674681 "/home/user" ,
675682 "gcc" ,
676683 vec ! [
677- ( ArgumentKind :: Source , vec![ "main.o" , "lib.o" ] ) ,
684+ ( ArgumentKind :: Source { binary: true } , vec![ "main.o" ] ) ,
685+ ( ArgumentKind :: Source { binary: true } , vec![ "lib.o" ] ) ,
678686 ( ArgumentKind :: Output , vec![ "-o" , "program" ] ) ,
679687 ( ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Linking ) ) , vec![ "-L/usr/lib" ] ) ,
680688 ] ,
@@ -695,7 +703,7 @@ mod tests {
695703 "gcc" ,
696704 vec ! [
697705 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
698- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
706+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
699707 ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
700708 ] ,
701709 ) ;
@@ -718,7 +726,7 @@ mod tests {
718726 "/home/user" ,
719727 "gcc" ,
720728 vec ! [
721- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
729+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
722730 ( ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Linking ) ) , vec![ "-L/usr/lib" ] ) ,
723731 ( ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Linking ) ) , vec![ "-lmath" ] ) ,
724732 ( ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Compiling ) ) , vec![ "-Wall" ] ) ,
@@ -765,8 +773,8 @@ mod tests {
765773 "/home/user" ,
766774 "gcc" ,
767775 vec ! [
768- ( ArgumentKind :: Source , vec![ "main.c" ] ) , // Real source file
769- ( ArgumentKind :: Source , vec![ "utils.cpp" ] ) , // Real source file
776+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) , // Real source file
777+ ( ArgumentKind :: Source { binary : false } , vec![ "utils.cpp" ] ) , // Real source file
770778 ( ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Linking ) ) , vec![ "-lm" ] ) ,
771779 ] ,
772780 ) ;
@@ -780,8 +788,8 @@ mod tests {
780788 "/home/user" ,
781789 "gcc" ,
782790 vec ! [
783- ( ArgumentKind :: Source , vec![ "main.o" ] ) , // Object file
784- ( ArgumentKind :: Source , vec![ "utils.a" ] ) , // Static library
791+ ( ArgumentKind :: Source { binary : true } , vec![ "main.o" ] ) , // Object file
792+ ( ArgumentKind :: Source { binary : true } , vec![ "utils.a" ] ) , // Static library
785793 ( ArgumentKind :: Output , vec![ "-o" , "program" ] ) ,
786794 ] ,
787795 ) ;
@@ -809,7 +817,7 @@ mod tests {
809817 ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Preprocessing ) ) ,
810818 vec![ "-E" ] , // Semantically classified as preprocessing
811819 ) ,
812- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
820+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
813821 ] ,
814822 ) ;
815823 let command = Command :: Compiler ( compiler_cmd) ;
@@ -825,7 +833,7 @@ mod tests {
825833 ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) ,
826834 vec![ "-c" ] , // Semantically classified as compiling
827835 ) ,
828- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
836+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
829837 ] ,
830838 ) ;
831839 let command = Command :: Compiler ( compiler_cmd) ;
@@ -850,7 +858,7 @@ mod tests {
850858 "/home/user" ,
851859 "gcc" ,
852860 vec ! [
853- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
861+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
854862 (
855863 ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Linking ) ) ,
856864 vec![ "-lmath" ] , // Semantically classified as linking
@@ -886,7 +894,7 @@ mod tests {
886894 vec ! [
887895 ( ArgumentKind :: Compiler , vec![ "gcc" ] ) ,
888896 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
889- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
897+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
890898 ( ArgumentKind :: Output , vec![ "-o" , "main.o" ] ) ,
891899 ] ,
892900 ) ;
@@ -931,7 +939,7 @@ mod tests {
931939 vec![ "-DWRAPPER_FLAG" ] ,
932940 ) ,
933941 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
934- ( ArgumentKind :: Source , vec![ "test.c" ] ) ,
942+ ( ArgumentKind :: Source { binary : false } , vec![ "test.c" ] ) ,
935943 ] ,
936944 ) ;
937945 let command = Command :: Compiler ( compiler_cmd) ;
@@ -968,7 +976,7 @@ mod tests {
968976 ArgumentKind :: Other ( PassEffect :: Configures ( CompilerPass :: Preprocessing ) ) ,
969977 vec![ "-DSOME_DEFINE" ] ,
970978 ) ,
971- ( ArgumentKind :: Source , vec![ "test.c" ] ) ,
979+ ( ArgumentKind :: Source { binary : false } , vec![ "test.c" ] ) ,
972980 ] ,
973981 ) ;
974982 let command = Command :: Compiler ( compiler_cmd) ;
@@ -992,7 +1000,7 @@ mod tests {
9921000 ( ArgumentKind :: Compiler , vec![ "gcc" ] ) ,
9931001 ( ArgumentKind :: Other ( PassEffect :: DriverOption ) , vec![ "-pipe" ] ) ,
9941002 ( ArgumentKind :: Other ( PassEffect :: StopsAt ( CompilerPass :: Compiling ) ) , vec![ "-c" ] ) ,
995- ( ArgumentKind :: Source , vec![ "main.c" ] ) ,
1003+ ( ArgumentKind :: Source { binary : false } , vec![ "main.c" ] ) ,
9961004 ] ,
9971005 ) ;
9981006 let command = Command :: Compiler ( compiler_cmd) ;
0 commit comments