@@ -4,7 +4,10 @@ use std::collections::HashMap;
4
4
use std:: env;
5
5
use std:: time:: Instant ;
6
6
7
- use ide:: { Analysis , Cancellable , RootDatabase , StaticIndex , StaticIndexedFile , TokenId , TokenStaticData } ;
7
+ use ide:: {
8
+ Analysis , Cancellable , FileId , FileRange , RootDatabase , StaticIndex , StaticIndexedFile ,
9
+ TokenId , TokenStaticData ,
10
+ } ;
8
11
use ide_db:: LineIndexDatabase ;
9
12
10
13
use ide_db:: base_db:: salsa:: { self , ParallelDatabase } ;
@@ -31,6 +34,8 @@ impl<DB: ParallelDatabase> Clone for Snap<salsa::Snapshot<DB>> {
31
34
struct LsifManager < ' a > {
32
35
count : i32 ,
33
36
token_map : HashMap < TokenId , Id > ,
37
+ range_map : HashMap < FileRange , Id > ,
38
+ file_map : HashMap < FileId , Id > ,
34
39
analysis : & ' a Analysis ,
35
40
db : & ' a RootDatabase ,
36
41
vfs : & ' a Vfs ,
@@ -50,12 +55,14 @@ impl LsifManager<'_> {
50
55
LsifManager {
51
56
count : 0 ,
52
57
token_map : HashMap :: default ( ) ,
58
+ range_map : HashMap :: default ( ) ,
59
+ file_map : HashMap :: default ( ) ,
53
60
analysis,
54
61
db,
55
62
vfs,
56
63
}
57
64
}
58
-
65
+
59
66
fn add ( & mut self , data : Element ) -> Id {
60
67
let id = Id ( self . count ) ;
61
68
self . emit ( & serde_json:: to_string ( & Entry { id : id. into ( ) , data } ) . unwrap ( ) ) ;
@@ -68,9 +75,54 @@ impl LsifManager<'_> {
68
75
println ! ( "{}" , data) ;
69
76
}
70
77
71
- fn add_token ( & mut self , id : TokenId , token : TokenStaticData ) {
78
+ fn get_token_id ( & mut self , id : TokenId ) -> Id {
79
+ if let Some ( x) = self . token_map . get ( & id) {
80
+ return * x;
81
+ }
72
82
let result_set_id = self . add ( Element :: Vertex ( Vertex :: ResultSet ( ResultSet { key : None } ) ) ) ;
73
83
self . token_map . insert ( id, result_set_id) ;
84
+ result_set_id
85
+ }
86
+
87
+ fn get_range_id ( & mut self , id : FileRange ) -> Cancellable < Id > {
88
+ if let Some ( x) = self . range_map . get ( & id) {
89
+ return Ok ( * x) ;
90
+ }
91
+ let file_id = id. file_id ;
92
+ let doc_id = self . get_file_id ( file_id) ;
93
+ let line_index = self . db . line_index ( file_id) ;
94
+ let line_index = LineIndex {
95
+ index : line_index. clone ( ) ,
96
+ encoding : OffsetEncoding :: Utf16 ,
97
+ endings : LineEndings :: Unix ,
98
+ } ;
99
+ let range_id = self . add ( Element :: Vertex ( Vertex :: Range {
100
+ range : to_proto:: range ( & line_index, id. range ) ,
101
+ tag : None ,
102
+ } ) ) ;
103
+ self . add ( Element :: Edge ( Edge :: Contains ( EdgeDataMultiIn {
104
+ in_vs : vec ! [ range_id. into( ) ] ,
105
+ out_v : doc_id. into ( ) ,
106
+ } ) ) ) ;
107
+ Ok ( range_id)
108
+ }
109
+
110
+ fn get_file_id ( & mut self , id : FileId ) -> Id {
111
+ if let Some ( x) = self . file_map . get ( & id) {
112
+ return * x;
113
+ }
114
+ let path = self . vfs . file_path ( id) ;
115
+ let path = path. as_path ( ) . unwrap ( ) ;
116
+ let doc_id = self . add ( Element :: Vertex ( Vertex :: Document ( Document {
117
+ language_id : "rust" . to_string ( ) ,
118
+ uri : lsp_types:: Url :: from_file_path ( path) . unwrap ( ) ,
119
+ } ) ) ) ;
120
+ self . file_map . insert ( id, doc_id) ;
121
+ doc_id
122
+ }
123
+
124
+ fn add_token ( & mut self , id : TokenId , token : TokenStaticData ) -> Cancellable < ( ) > {
125
+ let result_set_id = self . get_token_id ( id) ;
74
126
if let Some ( hover) = token. hover {
75
127
let hover_id = self . add ( Element :: Vertex ( Vertex :: HoverResult {
76
128
result : Hover {
@@ -83,16 +135,50 @@ impl LsifManager<'_> {
83
135
out_v : result_set_id. into ( ) ,
84
136
} ) ) ) ;
85
137
}
138
+ if let Some ( def) = token. definition {
139
+ let result_id = self . add ( Element :: Vertex ( Vertex :: DefinitionResult ) ) ;
140
+ let def_vertex = self . get_range_id ( def) ?;
141
+ self . add ( Element :: Edge ( Edge :: Item ( Item {
142
+ document : ( * self . file_map . get ( & def. file_id ) . unwrap ( ) ) . into ( ) ,
143
+ property : None ,
144
+ edge_data : EdgeDataMultiIn {
145
+ in_vs : vec ! [ def_vertex. into( ) ] ,
146
+ out_v : result_id. into ( ) ,
147
+ } ,
148
+ } ) ) ) ;
149
+ self . add ( Element :: Edge ( Edge :: Definition ( EdgeData {
150
+ in_v : result_id. into ( ) ,
151
+ out_v : result_set_id. into ( ) ,
152
+ } ) ) ) ;
153
+ }
154
+ if !token. references . is_empty ( ) {
155
+ let result_id = self . add ( Element :: Vertex ( Vertex :: ReferenceResult ) ) ;
156
+ self . add ( Element :: Edge ( Edge :: References ( EdgeData {
157
+ in_v : result_id. into ( ) ,
158
+ out_v : result_set_id. into ( ) ,
159
+ } ) ) ) ;
160
+ for x in token. references {
161
+ let vertex = * self . range_map . get ( & x. range ) . unwrap ( ) ;
162
+ self . add ( Element :: Edge ( Edge :: Item ( Item {
163
+ document : ( * self . file_map . get ( & x. range . file_id ) . unwrap ( ) ) . into ( ) ,
164
+ property : Some ( if x. is_definition {
165
+ ItemKind :: Definitions
166
+ } else {
167
+ ItemKind :: References
168
+ } ) ,
169
+ edge_data : EdgeDataMultiIn {
170
+ in_vs : vec ! [ vertex. into( ) ] ,
171
+ out_v : result_id. into ( ) ,
172
+ } ,
173
+ } ) ) ) ;
174
+ }
175
+ }
176
+ Ok ( ( ) )
86
177
}
87
178
88
179
fn add_file ( & mut self , file : StaticIndexedFile ) -> Cancellable < ( ) > {
89
- let StaticIndexedFile { file_id, tokens, folds} = file;
90
- let path = self . vfs . file_path ( file_id) ;
91
- let path = path. as_path ( ) . unwrap ( ) ;
92
- let doc_id = self . add ( Element :: Vertex ( Vertex :: Document ( Document {
93
- language_id : "rust" . to_string ( ) ,
94
- uri : lsp_types:: Url :: from_file_path ( path) . unwrap ( ) ,
95
- } ) ) ) ;
180
+ let StaticIndexedFile { file_id, tokens, folds } = file;
181
+ let doc_id = self . get_file_id ( file_id) ;
96
182
let text = self . analysis . file_text ( file_id) ?;
97
183
let line_index = self . db . line_index ( file_id) ;
98
184
let line_index = LineIndex {
@@ -116,7 +202,8 @@ impl LsifManager<'_> {
116
202
range : to_proto:: range ( & line_index, range) ,
117
203
tag : None ,
118
204
} ) ) ;
119
- let result_set_id = * self . token_map . get ( & id) . expect ( "token map doesn't contain id" ) ;
205
+ self . range_map . insert ( FileRange { file_id, range } , range_id) ;
206
+ let result_set_id = self . get_token_id ( id) ;
120
207
self . add ( Element :: Edge ( Edge :: Next ( EdgeData {
121
208
in_v : result_set_id. into ( ) ,
122
209
out_v : range_id. into ( ) ,
@@ -161,12 +248,12 @@ impl flags::Lsif {
161
248
position_encoding : Encoding :: Utf16 ,
162
249
tool_info : None ,
163
250
} ) ) ) ;
164
- for ( id, token) in si. tokens . iter ( ) {
165
- lsif. add_token ( id, token) ;
166
- }
167
251
for file in si. files {
168
252
lsif. add_file ( file) ?;
169
253
}
254
+ for ( id, token) in si. tokens . iter ( ) {
255
+ lsif. add_token ( id, token) ?;
256
+ }
170
257
eprintln ! ( "Generating LSIF finished in {:?}" , now. elapsed( ) ) ;
171
258
Ok ( ( ) )
172
259
}
0 commit comments