@@ -4,18 +4,61 @@ use std::sync::Arc;
4
4
5
5
use ra_cfg:: CfgOptions ;
6
6
use 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 } ;
8
8
9
9
use crate :: {
10
10
Analysis , AnalysisChange , AnalysisHost , CrateGraph , Edition :: Edition2018 , FileId , FilePosition ,
11
11
FileRange , SourceRootId ,
12
12
} ;
13
13
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
+
14
57
/// Mock analysis is used in test to bootstrap an AnalysisHost/Analysis
15
58
/// from a set of in-memory files.
16
59
#[ derive( Debug , Default ) ]
17
60
pub struct MockAnalysis {
18
- files : Vec < ( String , String ) > ,
61
+ files : Vec < MockFileData > ,
19
62
}
20
63
21
64
impl MockAnalysis {
@@ -35,7 +78,7 @@ impl MockAnalysis {
35
78
pub fn with_files ( fixture : & str ) -> MockAnalysis {
36
79
let mut res = MockAnalysis :: new ( ) ;
37
80
for entry in parse_fixture ( fixture) {
38
- res. add_file ( entry. meta . path ( ) . as_str ( ) , & entry . text ) ;
81
+ res. add_file_fixture ( entry) ;
39
82
}
40
83
res
41
84
}
@@ -48,39 +91,52 @@ impl MockAnalysis {
48
91
for entry in parse_fixture ( fixture) {
49
92
if entry. text . contains ( CURSOR_MARKER ) {
50
93
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) ) ;
53
95
} else {
54
- res. add_file ( & entry. meta . path ( ) . as_str ( ) , & entry . text ) ;
96
+ res. add_file_fixture ( entry) ;
55
97
}
56
98
}
57
99
let position = position. expect ( "expected a marker (<|>)" ) ;
58
100
( res, position)
59
101
}
60
102
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
+
61
117
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 ( ) ) ) ;
64
120
file_id
65
121
}
66
122
pub fn add_file_with_position ( & mut self , path : & str , text : & str ) -> FilePosition {
67
123
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) ) ;
70
126
FilePosition { file_id, offset }
71
127
}
72
128
pub fn add_file_with_range ( & mut self , path : & str , text : & str ) -> FileRange {
73
129
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) ) ;
76
132
FileRange { file_id, range }
77
133
}
78
134
pub fn id_of ( & self , path : & str ) -> FileId {
79
135
let ( idx, _) = self
80
136
. files
81
137
. iter ( )
82
138
. enumerate ( )
83
- . find ( |( _, ( p , _text ) ) | path == p )
139
+ . find ( |( _, data ) | path == data . path ( ) )
84
140
. expect ( "no file in this mock" ) ;
85
141
FileId ( idx as u32 + 1 )
86
142
}
@@ -91,11 +147,12 @@ impl MockAnalysis {
91
147
change. add_root ( source_root, true ) ;
92
148
let mut crate_graph = CrateGraph :: default ( ) ;
93
149
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 ( ) ;
95
152
assert ! ( path. starts_with( '/' ) ) ;
96
153
let path = RelativePathBuf :: from_path ( & path[ 1 ..] ) . unwrap ( ) ;
154
+ let cfg_options = data. cfg_options ( ) ;
97
155
let file_id = FileId ( i as u32 + 1 ) ;
98
- let cfg_options = CfgOptions :: default ( ) ;
99
156
if path == "/lib.rs" || path == "/main.rs" {
100
157
root_crate = Some ( crate_graph. add_crate_root (
101
158
file_id,
@@ -123,7 +180,7 @@ impl MockAnalysis {
123
180
. unwrap ( ) ;
124
181
}
125
182
}
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 ( ) ) ) ;
127
184
}
128
185
change. set_crate_graph ( crate_graph) ;
129
186
host. apply_change ( change) ;
@@ -132,6 +189,10 @@ impl MockAnalysis {
132
189
pub fn analysis ( self ) -> Analysis {
133
190
self . analysis_host ( ) . analysis ( )
134
191
}
192
+
193
+ fn next_id ( & self ) -> FileId {
194
+ FileId ( ( self . files . len ( ) + 1 ) as u32 )
195
+ }
135
196
}
136
197
137
198
/// Creates analysis from a multi-file fixture, returns positions marked with <|>.
0 commit comments