@@ -317,6 +317,7 @@ pub type KCLModuleCache = Arc<RwLock<ModuleCache>>;
317317#[ derive( Default , Debug ) ]
318318pub struct ModuleCache {
319319 pub ast_cache : IndexMap < PathBuf , Arc < ast:: Module > > ,
320+ pub file_pkg : IndexMap < PathBuf , HashSet < PkgFile > > ,
320321 pub dep_cache : IndexMap < PkgFile , ( Vec < PkgFile > , PkgMap ) > ,
321322}
322323struct Loader {
@@ -367,7 +368,7 @@ fn fix_rel_import_path_with_file(
367368 m : & mut ast:: Module ,
368369 file : & PkgFile ,
369370 pkgmap : & PkgMap ,
370- opts : LoadProgramOptions ,
371+ opts : & LoadProgramOptions ,
371372 sess : ParseSessionRef ,
372373) {
373374 for stmt in & mut m. body {
@@ -380,15 +381,15 @@ fn fix_rel_import_path_with_file(
380381 ) ;
381382 import_spec. path . node = fix_path. clone ( ) ;
382383
383- let pkg = pkgmap. get ( & file) . expect ( "file not in pkgmap" ) . clone ( ) ;
384+ let pkg = pkgmap. get ( & file) . expect ( "file not in pkgmap" ) ;
384385 import_spec. pkg_name = pkg. pkg_name . clone ( ) ;
385386 // Load the import package source code and compile.
386387 let pkg_info = find_packages (
387388 pos. into ( ) ,
388389 & pkg. pkg_name ,
389390 & pkg. pkg_root ,
390391 & fix_path,
391- opts. clone ( ) ,
392+ opts,
392393 sess. clone ( ) ,
393394 )
394395 . unwrap_or ( None ) ;
@@ -415,7 +416,7 @@ fn find_packages(
415416 pkg_name : & str ,
416417 pkg_root : & str ,
417418 pkg_path : & str ,
418- opts : LoadProgramOptions ,
419+ opts : & LoadProgramOptions ,
419420 sess : ParseSessionRef ,
420421) -> Result < Option < PkgInfo > > {
421422 if pkg_path. is_empty ( ) {
@@ -558,7 +559,7 @@ fn get_pkg_kfile_list(pkgroot: &str, pkgpath: &str) -> Result<Vec<String>> {
558559 }
559560
560561 if pkgroot. is_empty ( ) {
561- return Err ( anyhow:: anyhow!( "pkgroot not found" ) ) ;
562+ return Err ( anyhow:: anyhow!( format! ( "pkgroot not found: {:?}" , pkgpath ) ) ) ;
562563 }
563564
564565 let mut pathbuf = std:: path:: PathBuf :: new ( ) ;
@@ -623,7 +624,7 @@ fn get_dir_files(dir: &str) -> Result<Vec<String>> {
623624///
624625/// - [`is_external_pkg`] will return an error if the package's source files cannot be found.
625626/// - The name of the external package could not be resolved from [`pkg_path`].
626- fn is_external_pkg ( pkg_path : & str , opts : LoadProgramOptions ) -> Result < Option < PkgInfo > > {
627+ fn is_external_pkg ( pkg_path : & str , opts : & LoadProgramOptions ) -> Result < Option < PkgInfo > > {
627628 let pkg_name = parse_external_pkg_name ( pkg_path) ?;
628629 let external_pkg_root = if let Some ( root) = opts. package_maps . get ( & pkg_name) {
629630 PathBuf :: from ( root) . join ( KCL_MOD_FILE )
@@ -682,6 +683,16 @@ pub fn parse_file(
682683 module_cache
683684 . ast_cache
684685 . insert ( file. canonicalize ( ) , m. clone ( ) ) ;
686+ match module_cache. file_pkg . get_mut ( & file. canonicalize ( ) ) {
687+ Some ( s) => {
688+ s. insert ( file. clone ( ) ) ;
689+ }
690+ None => {
691+ let mut s = HashSet :: new ( ) ;
692+ s. insert ( file. clone ( ) ) ;
693+ module_cache. file_pkg . insert ( file. canonicalize ( ) , s) ;
694+ }
695+ }
685696 module_cache
686697 . dep_cache
687698 . insert ( file. clone ( ) , ( deps. clone ( ) , new_pkgmap) ) ;
@@ -722,7 +733,7 @@ pub fn get_deps(
722733 & pkg. pkg_name ,
723734 & pkg. pkg_root ,
724735 & fix_path,
725- opts. clone ( ) ,
736+ opts,
726737 sess. clone ( ) ,
727738 ) ?;
728739 if let Some ( pkg_info) = & pkg_info {
@@ -791,16 +802,18 @@ pub fn parse_entry(
791802 pkgmap : & mut PkgMap ,
792803 file_graph : FileGraphCache ,
793804 opts : & LoadProgramOptions ,
794- ) -> Result < ( ) > {
805+ ) -> Result < HashSet < PkgFile > > {
795806 let k_files = entry. get_k_files ( ) ;
796807 let maybe_k_codes = entry. get_k_codes ( ) ;
797808 let mut files = vec ! [ ] ;
809+ let mut new_files = HashSet :: new ( ) ;
798810 for ( i, f) in k_files. iter ( ) . enumerate ( ) {
799811 let file = PkgFile {
800812 path : f. adjust_canonicalization ( ) . into ( ) ,
801813 pkg_path : MAIN_PKG . to_string ( ) ,
802814 } ;
803815 files. push ( ( file. clone ( ) , maybe_k_codes. get ( i) . unwrap_or ( & None ) . clone ( ) ) ) ;
816+ new_files. insert ( file. clone ( ) ) ;
804817 pkgmap. insert (
805818 file,
806819 Pkg {
@@ -822,6 +835,24 @@ pub fn parse_entry(
822835 let mut parsed_file: HashSet < PkgFile > = HashSet :: new ( ) ;
823836 while let Some ( file) = unparsed_file. pop_front ( ) {
824837 if parsed_file. insert ( file. clone ( ) ) {
838+ match & mut module_cache. write ( ) {
839+ Ok ( m_cache) => match m_cache. file_pkg . get_mut ( & file. canonicalize ( ) ) {
840+ Some ( s) => {
841+ // The module ast has been parsed, but does not belong to the same package
842+ if s. insert ( file. clone ( ) ) {
843+ new_files. insert ( file. clone ( ) ) ;
844+ }
845+ }
846+ None => {
847+ let mut s = HashSet :: new ( ) ;
848+ s. insert ( file. clone ( ) ) ;
849+ m_cache. file_pkg . insert ( file. canonicalize ( ) , s) ;
850+ new_files. insert ( file. clone ( ) ) ;
851+ }
852+ } ,
853+ Err ( e) => return Err ( anyhow:: anyhow!( "Parse file failed: {e}" ) ) ,
854+ }
855+
825856 let module_cache_read = module_cache. read ( ) ;
826857 match & module_cache_read {
827858 Ok ( m_cache) => match m_cache. ast_cache . get ( & file. canonicalize ( ) ) {
@@ -849,6 +880,7 @@ pub fn parse_entry(
849880 }
850881 }
851882 None => {
883+ new_files. insert ( file. clone ( ) ) ;
852884 drop ( module_cache_read) ;
853885 let deps = parse_file (
854886 sess. clone ( ) ,
@@ -871,7 +903,7 @@ pub fn parse_entry(
871903 } ;
872904 }
873905 }
874- Ok ( ( ) )
906+ Ok ( new_files )
875907}
876908
877909pub fn parse_program (
@@ -885,16 +917,17 @@ pub fn parse_program(
885917 let workdir = compile_entries. get_root_path ( ) . to_string ( ) ;
886918 let mut pkgs: HashMap < String , Vec < Module > > = HashMap :: new ( ) ;
887919 let mut pkgmap = PkgMap :: new ( ) ;
920+ let mut new_files = HashSet :: new ( ) ;
888921 for entry in compile_entries. iter ( ) {
889- parse_entry (
922+ new_files . extend ( parse_entry (
890923 sess. clone ( ) ,
891924 entry,
892925 module_cache. clone ( ) ,
893926 & mut pkgs,
894927 & mut pkgmap,
895928 file_graph. clone ( ) ,
896929 & opts,
897- ) ?;
930+ ) ?) ;
898931 }
899932
900933 let files = match file_graph. read ( ) {
@@ -943,15 +976,15 @@ pub fn parse_program(
943976 . clone ( ) ,
944977 Err ( e) => return Err ( anyhow:: anyhow!( "Parse program failed: {e}" ) ) ,
945978 } ;
946- let pkg = pkgmap . get ( file) . expect ( "file not in pkgmap" ) ;
947- fix_rel_import_path_with_file (
948- & pkg. pkg_root ,
949- & mut m ,
950- file ,
951- & pkgmap ,
952- opts . clone ( ) ,
953- sess . clone ( ) ,
954- ) ;
979+ if new_files . contains ( file) {
980+ let pkg = pkgmap . get ( file ) . expect ( "file not in pkgmap" ) ;
981+ fix_rel_import_path_with_file ( & pkg. pkg_root , & mut m , file , & pkgmap , opts , sess . clone ( ) ) ;
982+ let m = Arc :: new ( m . clone ( ) ) ;
983+ match & mut module_cache . write ( ) {
984+ Ok ( module_cache ) => module_cache . ast_cache . insert ( file . canonicalize ( ) , m ) ,
985+ Err ( e ) => return Err ( anyhow :: anyhow! ( "Parse program failed: {e}" ) ) ,
986+ } ;
987+ }
955988
956989 match pkgs. get_mut ( & file. pkg_path ) {
957990 Some ( modules) => {
0 commit comments