@@ -655,14 +655,34 @@ def __init__(self, data_dir: str,
655655 self .fscache = fscache
656656 self .find_module_cache = FindModuleCache (self .fscache )
657657
658+ # a mapping from source files to their corresponding shadow files
659+ # for efficient lookup
660+ self .shadow_map = {} # type: Dict[str, str]
661+ if self .options .shadow_file is not None :
662+ self .shadow_map = {source_file : shadow_file
663+ for (source_file , shadow_file )
664+ in self .options .shadow_file }
665+ # a mapping from each file being typechecked to its possible shadow file
666+ self .shadow_equivalence_map = {} # type: Dict[str, Optional[str]]
667+
658668 def use_fine_grained_cache (self ) -> bool :
659669 return self .cache_enabled and self .options .use_fine_grained_cache
660670
661671 def maybe_swap_for_shadow_path (self , path : str ) -> str :
662- if (self .options .shadow_file and
663- os .path .samefile (self .options .shadow_file [0 ], path )):
664- path = self .options .shadow_file [1 ]
665- return path
672+ if not self .shadow_map :
673+ return path
674+
675+ previously_checked = path in self .shadow_equivalence_map
676+ if not previously_checked :
677+ for source , shadow in self .shadow_map .items ():
678+ if self .fscache .samefile (path , source ):
679+ self .shadow_equivalence_map [path ] = shadow
680+ break
681+ else :
682+ self .shadow_equivalence_map [path ] = None
683+
684+ shadow_file = self .shadow_equivalence_map .get (path )
685+ return shadow_file if shadow_file else path
666686
667687 def get_stat (self , path : str ) -> os .stat_result :
668688 return self .fscache .stat (self .maybe_swap_for_shadow_path (path ))
0 commit comments