@@ -48,6 +48,7 @@ use rustc::hir::def::Def;
48
48
use rustc:: hir:: map:: Node ;
49
49
use rustc:: hir:: def_id:: DefId ;
50
50
use rustc:: session:: config:: CrateType :: CrateTypeExecutable ;
51
+ use rustc:: session:: Session ;
51
52
use rustc:: ty:: { self , TyCtxt } ;
52
53
53
54
use std:: env;
@@ -866,55 +867,131 @@ impl Format {
866
867
}
867
868
}
868
869
869
- pub fn process_crate < ' l , ' tcx > ( tcx : TyCtxt < ' l , ' tcx , ' tcx > ,
870
- krate : & ast :: Crate ,
871
- analysis : & ' l ty :: CrateAnalysis ,
872
- cratename : & str ,
873
- odir : Option < & Path > ,
874
- format : Format ) {
875
- let _ignore = tcx . dep_graph . in_ignore ( ) ;
870
+ /// Defines what to do with the results of saving the analysis.
871
+ pub trait SaveHandler {
872
+ fn save < ' l , ' tcx > ( & mut self ,
873
+ save_ctxt : SaveContext < ' l , ' tcx > ,
874
+ krate : & ast :: Crate ,
875
+ cratename : & str ) ;
876
+ }
876
877
877
- assert ! ( analysis. glob_map. is_some( ) ) ;
878
+ /// Dump the save-analysis results to a file.
879
+ pub struct DumpHandler < ' a > {
880
+ format : Format ,
881
+ odir : Option < & ' a Path > ,
882
+ cratename : String
883
+ }
878
884
879
- info ! ( "Dumping crate {}" , cratename) ;
885
+ impl < ' a > DumpHandler < ' a > {
886
+ pub fn new ( format : Format , odir : Option < & ' a Path > , cratename : & str ) -> DumpHandler < ' a > {
887
+ DumpHandler {
888
+ format : format,
889
+ odir : odir,
890
+ cratename : cratename. to_owned ( )
891
+ }
892
+ }
880
893
881
- // find a path to dump our data to
882
- let mut root_path = match env:: var_os ( "RUST_SAVE_ANALYSIS_FOLDER" ) {
883
- Some ( val) => PathBuf :: from ( val) ,
884
- None => match odir {
885
- Some ( val) => val. join ( "save-analysis" ) ,
886
- None => PathBuf :: from ( "save-analysis-temp" ) ,
887
- } ,
888
- } ;
894
+ fn output_file ( & self , sess : & Session ) -> File {
895
+ let mut root_path = match env:: var_os ( "RUST_SAVE_ANALYSIS_FOLDER" ) {
896
+ Some ( val) => PathBuf :: from ( val) ,
897
+ None => match self . odir {
898
+ Some ( val) => val. join ( "save-analysis" ) ,
899
+ None => PathBuf :: from ( "save-analysis-temp" ) ,
900
+ } ,
901
+ } ;
889
902
890
- if let Err ( e) = std:: fs:: create_dir_all ( & root_path) {
891
- tcx. sess . err ( & format ! ( "Could not create directory {}: {}" ,
892
- root_path. display( ) ,
893
- e) ) ;
903
+ if let Err ( e) = std:: fs:: create_dir_all ( & root_path) {
904
+ error ! ( "Could not create directory {}: {}" , root_path. display( ) , e) ;
905
+ }
906
+
907
+ {
908
+ let disp = root_path. display ( ) ;
909
+ info ! ( "Writing output to {}" , disp) ;
910
+ }
911
+
912
+ let executable = sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == CrateTypeExecutable ) ;
913
+ let mut out_name = if executable {
914
+ "" . to_owned ( )
915
+ } else {
916
+ "lib" . to_owned ( )
917
+ } ;
918
+ out_name. push_str ( & self . cratename ) ;
919
+ out_name. push_str ( & sess. opts . cg . extra_filename ) ;
920
+ out_name. push_str ( self . format . extension ( ) ) ;
921
+ root_path. push ( & out_name) ;
922
+ let output_file = File :: create ( & root_path) . unwrap_or_else ( |e| {
923
+ let disp = root_path. display ( ) ;
924
+ sess. fatal ( & format ! ( "Could not open {}: {}" , disp, e) ) ;
925
+ } ) ;
926
+ root_path. pop ( ) ;
927
+ output_file
894
928
}
929
+ }
930
+
931
+ impl < ' a > SaveHandler for DumpHandler < ' a > {
932
+ fn save < ' l , ' tcx > ( & mut self ,
933
+ save_ctxt : SaveContext < ' l , ' tcx > ,
934
+ krate : & ast:: Crate ,
935
+ cratename : & str ) {
936
+ macro_rules! dump {
937
+ ( $new_dumper: expr) => { {
938
+ let mut dumper = $new_dumper;
939
+ let mut visitor = DumpVisitor :: new( save_ctxt, & mut dumper) ;
940
+
941
+ visitor. dump_crate_info( cratename, krate) ;
942
+ visit:: walk_crate( & mut visitor, krate) ;
943
+ } }
944
+ }
945
+
946
+ let output = & mut self . output_file ( & save_ctxt. tcx . sess ) ;
895
947
896
- {
897
- let disp = root_path. display ( ) ;
898
- info ! ( "Writing output to {}" , disp) ;
948
+ match self . format {
949
+ Format :: Csv => dump ! ( CsvDumper :: new( output) ) ,
950
+ Format :: Json => dump ! ( JsonDumper :: new( output) ) ,
951
+ Format :: JsonApi => dump ! ( JsonApiDumper :: new( output) ) ,
952
+ }
899
953
}
954
+ }
900
955
901
- // Create output file.
902
- let executable = tcx. sess . crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == CrateTypeExecutable ) ;
903
- let mut out_name = if executable {
904
- "" . to_owned ( )
905
- } else {
906
- "lib" . to_owned ( )
907
- } ;
908
- out_name. push_str ( & cratename) ;
909
- out_name. push_str ( & tcx. sess . opts . cg . extra_filename ) ;
910
- out_name. push_str ( format. extension ( ) ) ;
911
- root_path. push ( & out_name) ;
912
- let mut output_file = File :: create ( & root_path) . unwrap_or_else ( |e| {
913
- let disp = root_path. display ( ) ;
914
- tcx. sess . fatal ( & format ! ( "Could not open {}: {}" , disp, e) ) ;
915
- } ) ;
916
- root_path. pop ( ) ;
917
- let output = & mut output_file;
956
+ /// Call a callback with the results of save-analysis.
957
+ pub struct CallbackHandler < ' b > {
958
+ pub callback : & ' b mut FnMut ( & rls_data:: Analysis ) ,
959
+ }
960
+
961
+ impl < ' b > SaveHandler for CallbackHandler < ' b > {
962
+ fn save < ' l , ' tcx > ( & mut self ,
963
+ save_ctxt : SaveContext < ' l , ' tcx > ,
964
+ krate : & ast:: Crate ,
965
+ cratename : & str ) {
966
+ macro_rules! dump {
967
+ ( $new_dumper: expr) => { {
968
+ let mut dumper = $new_dumper;
969
+ let mut visitor = DumpVisitor :: new( save_ctxt, & mut dumper) ;
970
+
971
+ visitor. dump_crate_info( cratename, krate) ;
972
+ visit:: walk_crate( & mut visitor, krate) ;
973
+ } }
974
+ }
975
+
976
+ // We're using the JsonDumper here because it has the format of the
977
+ // save-analysis results that we will pass to the callback. IOW, we are
978
+ // using the JsonDumper to collect the save-analysis results, but not
979
+ // actually to dump them to a file. This is all a bit convoluted and
980
+ // there is certainly a simpler design here trying to get out (FIXME).
981
+ dump ! ( JsonDumper :: with_callback( self . callback) )
982
+ }
983
+ }
984
+
985
+ pub fn process_crate < ' l , ' tcx , H : SaveHandler > ( tcx : TyCtxt < ' l , ' tcx , ' tcx > ,
986
+ krate : & ast:: Crate ,
987
+ analysis : & ' l ty:: CrateAnalysis ,
988
+ cratename : & str ,
989
+ mut handler : H ) {
990
+ let _ignore = tcx. dep_graph . in_ignore ( ) ;
991
+
992
+ assert ! ( analysis. glob_map. is_some( ) ) ;
993
+
994
+ info ! ( "Dumping crate {}" , cratename) ;
918
995
919
996
let save_ctxt = SaveContext {
920
997
tcx : tcx,
@@ -923,21 +1000,7 @@ pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
923
1000
span_utils : SpanUtils :: new ( & tcx. sess ) ,
924
1001
} ;
925
1002
926
- macro_rules! dump {
927
- ( $new_dumper: expr) => { {
928
- let mut dumper = $new_dumper;
929
- let mut visitor = DumpVisitor :: new( save_ctxt, & mut dumper) ;
930
-
931
- visitor. dump_crate_info( cratename, krate) ;
932
- visit:: walk_crate( & mut visitor, krate) ;
933
- } }
934
- }
935
-
936
- match format {
937
- Format :: Csv => dump ! ( CsvDumper :: new( output) ) ,
938
- Format :: Json => dump ! ( JsonDumper :: new( output) ) ,
939
- Format :: JsonApi => dump ! ( JsonApiDumper :: new( output) ) ,
940
- }
1003
+ handler. save ( save_ctxt, krate, cratename)
941
1004
}
942
1005
943
1006
// Utility functions for the module.
0 commit comments