@@ -4,18 +4,61 @@ use std::sync::Arc;
44
55use ra_cfg:: CfgOptions ;
66use ra_db:: { CrateName , Env , RelativePathBuf } ;
7- use test_utils:: { extract_offset, extract_range, parse_fixture, CURSOR_MARKER } ;
7+ use test_utils:: { extract_offset, extract_range, parse_fixture, FixtureEntry , CURSOR_MARKER } ;
88
99use crate :: {
1010 Analysis , AnalysisChange , AnalysisHost , CrateGraph , Edition :: Edition2018 , FileId , FilePosition ,
1111 FileRange , SourceRootId ,
1212} ;
1313
14+ #[ derive( Debug ) ]
15+ enum MockFileData {
16+ Plain { path : String , content : String } ,
17+ Fixture ( FixtureEntry ) ,
18+ }
19+
20+ impl MockFileData {
21+ fn new ( path : String , content : String ) -> Self {
22+ // `Self::Plain` causes a false warning: 'variant is never constructed: `Plain` '
23+ // see https://github.com/rust-lang/rust/issues/69018
24+ MockFileData :: Plain { path, content }
25+ }
26+
27+ fn path ( & self ) -> & str {
28+ match self {
29+ MockFileData :: Plain { path, .. } => path. as_str ( ) ,
30+ MockFileData :: Fixture ( f) => f. meta . path ( ) . as_str ( ) ,
31+ }
32+ }
33+
34+ fn content ( & self ) -> & str {
35+ match self {
36+ MockFileData :: Plain { content, .. } => content,
37+ MockFileData :: Fixture ( f) => f. text . as_str ( ) ,
38+ }
39+ }
40+
41+ fn cfg_options ( & self ) -> CfgOptions {
42+ match self {
43+ MockFileData :: Fixture ( f) => {
44+ f. meta . cfg_options ( ) . map_or_else ( Default :: default, |o| o. clone ( ) )
45+ }
46+ _ => CfgOptions :: default ( ) ,
47+ }
48+ }
49+ }
50+
51+ impl From < FixtureEntry > for MockFileData {
52+ fn from ( fixture : FixtureEntry ) -> Self {
53+ Self :: Fixture ( fixture)
54+ }
55+ }
56+
1457/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis
1558/// from a set of in-memory files.
1659#[ derive( Debug , Default ) ]
1760pub struct MockAnalysis {
18- files : Vec < ( String , String ) > ,
61+ files : Vec < MockFileData > ,
1962}
2063
2164impl MockAnalysis {
@@ -35,7 +78,7 @@ impl MockAnalysis {
3578 pub fn with_files ( fixture : & str ) -> MockAnalysis {
3679 let mut res = MockAnalysis :: new ( ) ;
3780 for entry in parse_fixture ( fixture) {
38- res. add_file ( entry. meta . path ( ) . as_str ( ) , & entry . text ) ;
81+ res. add_file_fixture ( entry) ;
3982 }
4083 res
4184 }
@@ -48,39 +91,52 @@ impl MockAnalysis {
4891 for entry in parse_fixture ( fixture) {
4992 if entry. text . contains ( CURSOR_MARKER ) {
5093 assert ! ( position. is_none( ) , "only one marker (<|>) per fixture is allowed" ) ;
51- position =
52- Some ( res. add_file_with_position ( & entry. meta . path ( ) . as_str ( ) , & entry. text ) ) ;
94+ position = Some ( res. add_file_fixture_with_position ( entry) ) ;
5395 } else {
54- res. add_file ( & entry. meta . path ( ) . as_str ( ) , & entry . text ) ;
96+ res. add_file_fixture ( entry) ;
5597 }
5698 }
5799 let position = position. expect ( "expected a marker (<|>)" ) ;
58100 ( res, position)
59101 }
60102
103+ pub fn add_file_fixture ( & mut self , fixture : FixtureEntry ) -> FileId {
104+ let file_id = self . next_id ( ) ;
105+ self . files . push ( MockFileData :: from ( fixture) ) ;
106+ file_id
107+ }
108+
109+ pub fn add_file_fixture_with_position ( & mut self , mut fixture : FixtureEntry ) -> FilePosition {
110+ let ( offset, text) = extract_offset ( & fixture. text ) ;
111+ fixture. text = text;
112+ let file_id = self . next_id ( ) ;
113+ self . files . push ( MockFileData :: from ( fixture) ) ;
114+ FilePosition { file_id, offset }
115+ }
116+
61117 pub fn add_file ( & mut self , path : & str , text : & str ) -> FileId {
62- let file_id = FileId ( ( self . files . len ( ) + 1 ) as u32 ) ;
63- self . files . push ( ( path. to_string ( ) , text. to_string ( ) ) ) ;
118+ let file_id = self . next_id ( ) ;
119+ self . files . push ( MockFileData :: new ( path. to_string ( ) , text. to_string ( ) ) ) ;
64120 file_id
65121 }
66122 pub fn add_file_with_position ( & mut self , path : & str , text : & str ) -> FilePosition {
67123 let ( offset, text) = extract_offset ( text) ;
68- let file_id = FileId ( ( self . files . len ( ) + 1 ) as u32 ) ;
69- self . files . push ( ( path. to_string ( ) , text) ) ;
124+ let file_id = self . next_id ( ) ;
125+ self . files . push ( MockFileData :: new ( path. to_string ( ) , text) ) ;
70126 FilePosition { file_id, offset }
71127 }
72128 pub fn add_file_with_range ( & mut self , path : & str , text : & str ) -> FileRange {
73129 let ( range, text) = extract_range ( text) ;
74- let file_id = FileId ( ( self . files . len ( ) + 1 ) as u32 ) ;
75- self . files . push ( ( path. to_string ( ) , text) ) ;
130+ let file_id = self . next_id ( ) ;
131+ self . files . push ( MockFileData :: new ( path. to_string ( ) , text) ) ;
76132 FileRange { file_id, range }
77133 }
78134 pub fn id_of ( & self , path : & str ) -> FileId {
79135 let ( idx, _) = self
80136 . files
81137 . iter ( )
82138 . enumerate ( )
83- . find ( |( _, ( p , _text ) ) | path == p )
139+ . find ( |( _, data ) | path == data . path ( ) )
84140 . expect ( "no file in this mock" ) ;
85141 FileId ( idx as u32 + 1 )
86142 }
@@ -91,11 +147,12 @@ impl MockAnalysis {
91147 change. add_root ( source_root, true ) ;
92148 let mut crate_graph = CrateGraph :: default ( ) ;
93149 let mut root_crate = None ;
94- for ( i, ( path, contents) ) in self . files . into_iter ( ) . enumerate ( ) {
150+ for ( i, data) in self . files . into_iter ( ) . enumerate ( ) {
151+ let path = data. path ( ) ;
95152 assert ! ( path. starts_with( '/' ) ) ;
96153 let path = RelativePathBuf :: from_path ( & path[ 1 ..] ) . unwrap ( ) ;
154+ let cfg_options = data. cfg_options ( ) ;
97155 let file_id = FileId ( i as u32 + 1 ) ;
98- let cfg_options = CfgOptions :: default ( ) ;
99156 if path == "/lib.rs" || path == "/main.rs" {
100157 root_crate = Some ( crate_graph. add_crate_root (
101158 file_id,
@@ -123,7 +180,7 @@ impl MockAnalysis {
123180 . unwrap ( ) ;
124181 }
125182 }
126- change. add_file ( source_root, file_id, path, Arc :: new ( contents ) ) ;
183+ change. add_file ( source_root, file_id, path, Arc :: new ( data . content ( ) . to_owned ( ) ) ) ;
127184 }
128185 change. set_crate_graph ( crate_graph) ;
129186 host. apply_change ( change) ;
@@ -132,6 +189,10 @@ impl MockAnalysis {
132189 pub fn analysis ( self ) -> Analysis {
133190 self . analysis_host ( ) . analysis ( )
134191 }
192+
193+ fn next_id ( & self ) -> FileId {
194+ FileId ( ( self . files . len ( ) + 1 ) as u32 )
195+ }
135196}
136197
137198/// Creates analysis from a multi-file fixture, returns positions marked with <|>.
0 commit comments