@@ -8,8 +8,8 @@ use std::{
88use crate :: line_index:: { LineEndings , LineIndex , OffsetEncoding } ;
99use hir:: Name ;
1010use ide:: {
11- LineCol , MonikerDescriptorKind , MonikerResult , StaticIndex , StaticIndexedFile , TextRange ,
12- TokenId ,
11+ LineCol , MonikerDescriptorKind , StaticIndex , StaticIndexedFile , TextRange , TokenId ,
12+ TokenStaticData ,
1313} ;
1414use ide_db:: LineIndexDatabase ;
1515use project_model:: { CargoConfig , ProjectManifest , ProjectWorkspace } ;
@@ -75,7 +75,7 @@ impl flags::Scip {
7575 let mut symbols_emitted: HashSet < TokenId > = HashSet :: default ( ) ;
7676 let mut tokens_to_symbol: HashMap < TokenId , String > = HashMap :: new ( ) ;
7777
78- for file in si. files {
78+ for StaticIndexedFile { file_id , tokens , .. } in si. files {
7979 let mut local_count = 0 ;
8080 let mut new_local_symbol = || {
8181 let new_symbol = scip:: types:: Symbol :: new_local ( local_count) ;
@@ -84,7 +84,6 @@ impl flags::Scip {
8484 new_symbol
8585 } ;
8686
87- let StaticIndexedFile { file_id, tokens, .. } = file;
8887 let relative_path = match get_relative_filepath ( & vfs, & rootpath, file_id) {
8988 Some ( relative_path) => relative_path,
9089 None => continue ,
@@ -107,28 +106,20 @@ impl flags::Scip {
107106
108107 let mut occurrence = scip_types:: Occurrence :: default ( ) ;
109108 occurrence. range = text_range_to_scip_range ( & line_index, range) ;
110- occurrence. symbol = match tokens_to_symbol. get ( & id) {
111- Some ( symbol) => symbol. clone ( ) ,
112- None => {
113- let symbol = match & token. moniker {
114- Some ( moniker) => moniker_to_symbol ( & moniker) ,
115- None => new_local_symbol ( ) ,
116- } ;
117-
118- let symbol = scip:: symbol:: format_symbol ( symbol) ;
119- tokens_to_symbol. insert ( id, symbol. clone ( ) ) ;
120- symbol
121- }
122- } ;
109+ occurrence. symbol = tokens_to_symbol
110+ . entry ( id)
111+ . or_insert_with ( || {
112+ let symbol = token_to_symbol ( & token) . unwrap_or_else ( & mut new_local_symbol) ;
113+ scip:: symbol:: format_symbol ( symbol)
114+ } )
115+ . clone ( ) ;
123116
124117 if let Some ( def) = token. definition {
125118 if def. range == range {
126119 occurrence. symbol_roles |= scip_types:: SymbolRole :: Definition as i32 ;
127120 }
128121
129- if !symbols_emitted. contains ( & id) {
130- symbols_emitted. insert ( id) ;
131-
122+ if symbols_emitted. insert ( id) {
132123 let mut symbol_info = scip_types:: SymbolInformation :: default ( ) ;
133124 symbol_info. symbol = occurrence. symbol . clone ( ) ;
134125 if let Some ( hover) = & token. hover {
@@ -207,9 +198,11 @@ fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_ty
207198///
208199/// Only returns a Symbol when it's a non-local symbol.
209200/// So if the visibility isn't outside of a document, then it will return None
210- fn moniker_to_symbol ( moniker : & MonikerResult ) -> scip_types:: Symbol {
201+ fn token_to_symbol ( token : & TokenStaticData ) -> Option < scip_types:: Symbol > {
211202 use scip_types:: descriptor:: Suffix :: * ;
212203
204+ let moniker = token. moniker . as_ref ( ) ?;
205+
213206 let package_name = moniker. package_information . name . clone ( ) ;
214207 let version = moniker. package_information . version . clone ( ) ;
215208 let descriptors = moniker
@@ -233,7 +226,7 @@ fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
233226 } )
234227 . collect ( ) ;
235228
236- scip_types:: Symbol {
229+ Some ( scip_types:: Symbol {
237230 scheme : "rust-analyzer" . into ( ) ,
238231 package : Some ( scip_types:: Package {
239232 manager : "cargo" . to_string ( ) ,
@@ -244,19 +237,15 @@ fn moniker_to_symbol(moniker: &MonikerResult) -> scip_types::Symbol {
244237 . into ( ) ,
245238 descriptors,
246239 ..Default :: default ( )
247- }
240+ } )
248241}
249242
250243#[ cfg( test) ]
251244mod test {
252245 use super :: * ;
253- use hir:: Semantics ;
254- use ide:: { AnalysisHost , FilePosition } ;
255- use ide_db:: defs:: IdentClass ;
256- use ide_db:: { base_db:: fixture:: ChangeFixture , helpers:: pick_best_token} ;
246+ use ide:: { AnalysisHost , FilePosition , StaticIndex , TextSize } ;
247+ use ide_db:: base_db:: fixture:: ChangeFixture ;
257248 use scip:: symbol:: format_symbol;
258- use syntax:: SyntaxKind :: * ;
259- use syntax:: { AstNode , T } ;
260249
261250 fn position ( ra_fixture : & str ) -> ( AnalysisHost , FilePosition ) {
262251 let mut host = AnalysisHost :: default ( ) ;
@@ -273,53 +262,33 @@ mod test {
273262 fn check_symbol ( ra_fixture : & str , expected : & str ) {
274263 let ( host, position) = position ( ra_fixture) ;
275264
265+ let analysis = host. analysis ( ) ;
266+ let si = StaticIndex :: compute ( & analysis) ;
267+
276268 let FilePosition { file_id, offset } = position;
277269
278- let db = host. raw_database ( ) ;
279- let sema = & Semantics :: new ( db) ;
280- let file = sema. parse ( file_id) . syntax ( ) . clone ( ) ;
281- let original_token = pick_best_token ( file. token_at_offset ( offset) , |kind| match kind {
282- IDENT
283- | INT_NUMBER
284- | LIFETIME_IDENT
285- | T ! [ self ]
286- | T ! [ super ]
287- | T ! [ crate ]
288- | T ! [ Self ]
289- | COMMENT => 2 ,
290- kind if kind. is_trivia ( ) => 0 ,
291- _ => 1 ,
292- } )
293- . expect ( "OK OK" ) ;
294-
295- let navs = sema
296- . descend_into_macros ( original_token. clone ( ) )
297- . into_iter ( )
298- . filter_map ( |token| {
299- IdentClass :: classify_token ( sema, & token) . map ( IdentClass :: definitions) . map ( |it| {
300- it. into_iter ( ) . flat_map ( |def| {
301- let module = def. module ( db) . unwrap ( ) ;
302- let current_crate = module. krate ( ) ;
303-
304- match MonikerResult :: from_def ( sema. db , def, current_crate) {
305- Some ( moniker_result) => Some ( moniker_to_symbol ( & moniker_result) ) ,
306- None => None ,
307- }
308- } )
309- } )
310- } )
311- . flatten ( )
312- . collect :: < Vec < _ > > ( ) ;
270+ let mut found_symbol = None ;
271+ for file in & si. files {
272+ if file. file_id != file_id {
273+ continue ;
274+ }
275+ for & ( range, id) in & file. tokens {
276+ if range. contains ( offset - TextSize :: from ( 1 ) ) {
277+ let token = si. tokens . get ( id) . unwrap ( ) ;
278+ found_symbol = token_to_symbol ( token) ;
279+ break ;
280+ }
281+ }
282+ }
313283
314284 if expected == "" {
315- assert_eq ! ( 0 , navs . len ( ) , "must have no symbols {:?}" , navs ) ;
285+ assert ! ( found_symbol . is_none ( ) , "must have no symbols {:?}" , found_symbol ) ;
316286 return ;
317287 }
318288
319- assert_eq ! ( 1 , navs. len( ) , "must have one symbol {:?}" , navs) ;
320-
321- let res = navs. get ( 0 ) . unwrap ( ) ;
322- let formatted = format_symbol ( res. clone ( ) ) ;
289+ assert ! ( found_symbol. is_some( ) , "must have one symbol {:?}" , found_symbol) ;
290+ let res = found_symbol. unwrap ( ) ;
291+ let formatted = format_symbol ( res) ;
323292 assert_eq ! ( formatted, expected) ;
324293 }
325294
0 commit comments