1
1
use std:: {
2
+ fmt,
2
3
hash:: { Hash , Hasher } ,
3
4
sync:: Arc ,
4
5
} ;
@@ -92,26 +93,26 @@ pub(crate) struct AnalysisHostImpl {
92
93
93
94
impl AnalysisHostImpl {
94
95
pub fn new ( ) -> AnalysisHostImpl {
95
- let db = db:: RootDatabase :: default ( ) ;
96
- db. query ( crate :: input:: SourceRootQuery )
96
+ let mut db = db:: RootDatabase :: default ( ) ;
97
+ db. query_mut ( crate :: input:: SourceRootQuery )
97
98
. set ( WORKSPACE , Default :: default ( ) ) ;
98
- db. query ( crate :: input:: CrateGraphQuery )
99
+ db. query_mut ( crate :: input:: CrateGraphQuery )
99
100
. set ( ( ) , Default :: default ( ) ) ;
100
- db. query ( crate :: input:: LibrariesQuery )
101
+ db. query_mut ( crate :: input:: LibrariesQuery )
101
102
. set ( ( ) , Default :: default ( ) ) ;
102
103
AnalysisHostImpl { db }
103
104
}
104
105
pub fn analysis ( & self ) -> AnalysisImpl {
105
106
AnalysisImpl {
106
- db : self . db . fork ( ) , // freeze revision here
107
+ db : self . db . snapshot ( ) ,
107
108
}
108
109
}
109
110
pub fn apply_change ( & mut self , change : AnalysisChange ) {
110
111
log:: info!( "apply_change {:?}" , change) ;
111
112
112
113
for ( file_id, text) in change. files_changed {
113
114
self . db
114
- . query ( crate :: input:: FileTextQuery )
115
+ . query_mut ( crate :: input:: FileTextQuery )
115
116
. set ( file_id, Arc :: new ( text) )
116
117
}
117
118
if !( change. files_added . is_empty ( ) && change. files_removed . is_empty ( ) ) {
@@ -121,22 +122,22 @@ impl AnalysisHostImpl {
121
122
let mut source_root = SourceRoot :: clone ( & self . db . source_root ( WORKSPACE ) ) ;
122
123
for ( file_id, text) in change. files_added {
123
124
self . db
124
- . query ( crate :: input:: FileTextQuery )
125
+ . query_mut ( crate :: input:: FileTextQuery )
125
126
. set ( file_id, Arc :: new ( text) ) ;
126
127
self . db
127
- . query ( crate :: input:: FileSourceRootQuery )
128
+ . query_mut ( crate :: input:: FileSourceRootQuery )
128
129
. set ( file_id, crate :: input:: WORKSPACE ) ;
129
130
source_root. files . insert ( file_id) ;
130
131
}
131
132
for file_id in change. files_removed {
132
133
self . db
133
- . query ( crate :: input:: FileTextQuery )
134
+ . query_mut ( crate :: input:: FileTextQuery )
134
135
. set ( file_id, Arc :: new ( String :: new ( ) ) ) ;
135
136
source_root. files . remove ( & file_id) ;
136
137
}
137
138
source_root. file_resolver = file_resolver;
138
139
self . db
139
- . query ( crate :: input:: SourceRootQuery )
140
+ . query_mut ( crate :: input:: SourceRootQuery )
140
141
. set ( WORKSPACE , Arc :: new ( source_root) )
141
142
}
142
143
if !change. libraries_added . is_empty ( ) {
@@ -148,38 +149,44 @@ impl AnalysisHostImpl {
148
149
for ( file_id, text) in library. files {
149
150
files. insert ( file_id) ;
150
151
self . db
151
- . query ( crate :: input:: FileSourceRootQuery )
152
+ . query_mut ( crate :: input:: FileSourceRootQuery )
152
153
. set_constant ( file_id, source_root_id) ;
153
154
self . db
154
- . query ( crate :: input:: FileTextQuery )
155
+ . query_mut ( crate :: input:: FileTextQuery )
155
156
. set_constant ( file_id, Arc :: new ( text) ) ;
156
157
}
157
158
let source_root = SourceRoot {
158
159
files,
159
160
file_resolver : library. file_resolver ,
160
161
} ;
161
162
self . db
162
- . query ( crate :: input:: SourceRootQuery )
163
+ . query_mut ( crate :: input:: SourceRootQuery )
163
164
. set ( source_root_id, Arc :: new ( source_root) ) ;
164
165
self . db
165
- . query ( crate :: input:: LibrarySymbolsQuery )
166
+ . query_mut ( crate :: input:: LibrarySymbolsQuery )
166
167
. set ( source_root_id, Arc :: new ( library. symbol_index ) ) ;
167
168
}
168
169
self . db
169
- . query ( crate :: input:: LibrariesQuery )
170
+ . query_mut ( crate :: input:: LibrariesQuery )
170
171
. set ( ( ) , Arc :: new ( libraries) ) ;
171
172
}
172
173
if let Some ( crate_graph) = change. crate_graph {
173
174
self . db
174
- . query ( crate :: input:: CrateGraphQuery )
175
+ . query_mut ( crate :: input:: CrateGraphQuery )
175
176
. set ( ( ) , Arc :: new ( crate_graph) )
176
177
}
177
178
}
178
179
}
179
180
180
- #[ derive( Debug ) ]
181
181
pub ( crate ) struct AnalysisImpl {
182
- pub ( crate ) db : db:: RootDatabase ,
182
+ pub ( crate ) db : salsa:: Snapshot < db:: RootDatabase > ,
183
+ }
184
+
185
+ impl fmt:: Debug for AnalysisImpl {
186
+ fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
187
+ let db: & db:: RootDatabase = & self . db ;
188
+ fmt. debug_struct ( "AnalysisImpl" ) . field ( "db" , db) . finish ( )
189
+ }
183
190
}
184
191
185
192
impl AnalysisImpl {
@@ -198,10 +205,19 @@ impl AnalysisImpl {
198
205
. collect ( )
199
206
} else {
200
207
let files = & self . db . source_root ( WORKSPACE ) . files ;
201
- let db = self . db . clone ( ) ;
208
+
209
+ /// Need to wrap Snapshot to provide `Clon` impl for `map_with`
210
+ struct Snap ( salsa:: Snapshot < db:: RootDatabase > ) ;
211
+ impl Clone for Snap {
212
+ fn clone ( & self ) -> Snap {
213
+ Snap ( self . 0 . snapshot ( ) )
214
+ }
215
+ }
216
+
217
+ let snap = Snap ( self . db . snapshot ( ) ) ;
202
218
files
203
219
. par_iter ( )
204
- . map_with ( db , |db, & file_id| db. file_symbols ( file_id) )
220
+ . map_with ( snap , |db, & file_id| db. 0 . file_symbols ( file_id) )
205
221
. filter_map ( |it| it. ok ( ) )
206
222
. collect ( )
207
223
} ;
@@ -229,7 +245,7 @@ impl AnalysisImpl {
229
245
return None ;
230
246
}
231
247
} ;
232
- let decl = link. bind_source ( & module_tree, & self . db ) ;
248
+ let decl = link. bind_source ( & module_tree, & * self . db ) ;
233
249
let decl = decl. ast ( ) ;
234
250
235
251
let sym = FileSymbol {
@@ -371,7 +387,7 @@ impl AnalysisImpl {
371
387
} )
372
388
. collect :: < Vec < _ > > ( ) ;
373
389
if let Some ( m) = module_tree. any_module_for_file ( file_id) {
374
- for ( name_node, problem) in m. problems ( & module_tree, & self . db ) {
390
+ for ( name_node, problem) in m. problems ( & module_tree, & * self . db ) {
375
391
let diag = match problem {
376
392
Problem :: UnresolvedModule { candidate } => {
377
393
let create_file = FileSystemEdit :: CreateFile {
0 commit comments