1
- use std:: fmt;
2
-
3
- use rustc_hash:: FxHashMap ;
1
+ use rustc_hash:: { FxHashMap , FxHashSet } ;
4
2
5
3
use ra_syntax:: {
6
4
algo:: generate,
7
5
ast:: { self , ArgListOwner , LoopBodyOwner , NameOwner } ,
8
- AstNode , SmolStr , SyntaxNode , SyntaxNodeRef ,
6
+ AstNode , SmolStr , SyntaxNodeRef ,
9
7
} ;
10
8
11
- type ScopeId = usize ;
9
+ use crate :: syntax_ptr:: LocalSyntaxPtr ;
10
+
11
+ #[ derive( Clone , Copy , PartialEq , Eq , Debug ) ]
12
+ pub ( crate ) struct ScopeId ( u32 ) ;
12
13
13
- #[ derive( Debug ) ]
14
+ #[ derive( Debug , PartialEq , Eq ) ]
14
15
pub struct FnScopes {
15
- pub self_param : Option < SyntaxNode > ,
16
+ pub ( crate ) self_param : Option < LocalSyntaxPtr > ,
16
17
scopes : Vec < ScopeData > ,
17
- scope_for : FxHashMap < SyntaxNode , ScopeId > ,
18
+ scope_for : FxHashMap < LocalSyntaxPtr , ScopeId > ,
19
+ }
20
+
21
+ #[ derive( Debug , PartialEq , Eq ) ]
22
+ pub struct ScopeEntry {
23
+ name : SmolStr ,
24
+ ptr : LocalSyntaxPtr ,
25
+ }
26
+
27
+ #[ derive( Debug , PartialEq , Eq ) ]
28
+ struct ScopeData {
29
+ parent : Option < ScopeId > ,
30
+ entries : Vec < ScopeEntry > ,
18
31
}
19
32
20
33
impl FnScopes {
21
- pub fn new ( fn_def : ast:: FnDef ) -> FnScopes {
34
+ pub ( crate ) fn new ( fn_def : ast:: FnDef ) -> FnScopes {
22
35
let mut scopes = FnScopes {
23
36
self_param : fn_def
24
37
. param_list ( )
25
38
. and_then ( |it| it. self_param ( ) )
26
- . map ( |it| it. syntax ( ) . owned ( ) ) ,
39
+ . map ( |it| LocalSyntaxPtr :: new ( it. syntax ( ) ) ) ,
27
40
scopes : Vec :: new ( ) ,
28
41
scope_for : FxHashMap :: default ( ) ,
29
42
} ;
@@ -34,24 +47,24 @@ impl FnScopes {
34
47
}
35
48
scopes
36
49
}
37
- pub fn entries ( & self , scope : ScopeId ) -> & [ ScopeEntry ] {
38
- & self . scopes [ scope] . entries
50
+ pub ( crate ) fn entries ( & self , scope : ScopeId ) -> & [ ScopeEntry ] {
51
+ & self . get ( scope) . entries
39
52
}
40
53
pub fn scope_chain < ' a > ( & ' a self , node : SyntaxNodeRef ) -> impl Iterator < Item = ScopeId > + ' a {
41
54
generate ( self . scope_for ( node) , move |& scope| {
42
- self . scopes [ scope] . parent
55
+ self . get ( scope) . parent
43
56
} )
44
57
}
45
58
fn root_scope ( & mut self ) -> ScopeId {
46
- let res = self . scopes . len ( ) ;
59
+ let res = ScopeId ( self . scopes . len ( ) as u32 ) ;
47
60
self . scopes . push ( ScopeData {
48
61
parent : None ,
49
62
entries : vec ! [ ] ,
50
63
} ) ;
51
64
res
52
65
}
53
66
fn new_scope ( & mut self , parent : ScopeId ) -> ScopeId {
54
- let res = self . scopes . len ( ) ;
67
+ let res = ScopeId ( self . scopes . len ( ) as u32 ) ;
55
68
self . scopes . push ( ScopeData {
56
69
parent : Some ( parent) ,
57
70
entries : vec ! [ ] ,
@@ -64,7 +77,7 @@ impl FnScopes {
64
77
. descendants ( )
65
78
. filter_map ( ast:: BindPat :: cast)
66
79
. filter_map ( ScopeEntry :: new) ;
67
- self . scopes [ scope] . entries . extend ( entries) ;
80
+ self . get_mut ( scope) . entries . extend ( entries) ;
68
81
}
69
82
fn add_params_bindings ( & mut self , scope : ScopeId , params : Option < ast:: ParamList > ) {
70
83
params
@@ -74,43 +87,36 @@ impl FnScopes {
74
87
. for_each ( |it| self . add_bindings ( scope, it) ) ;
75
88
}
76
89
fn set_scope ( & mut self , node : SyntaxNodeRef , scope : ScopeId ) {
77
- self . scope_for . insert ( node . owned ( ) , scope) ;
90
+ self . scope_for . insert ( LocalSyntaxPtr :: new ( node ) , scope) ;
78
91
}
79
92
fn scope_for ( & self , node : SyntaxNodeRef ) -> Option < ScopeId > {
80
93
node. ancestors ( )
81
- . filter_map ( |it| self . scope_for . get ( & it. owned ( ) ) . map ( |& scope| scope) )
94
+ . map ( LocalSyntaxPtr :: new)
95
+ . filter_map ( |it| self . scope_for . get ( & it) . map ( |& scope| scope) )
82
96
. next ( )
83
97
}
84
- }
85
-
86
- pub struct ScopeEntry {
87
- syntax : SyntaxNode ,
98
+ fn get ( & self , scope : ScopeId ) -> & ScopeData {
99
+ & self . scopes [ scope. 0 as usize ]
100
+ }
101
+ fn get_mut ( & mut self , scope : ScopeId ) -> & mut ScopeData {
102
+ & mut self . scopes [ scope. 0 as usize ]
103
+ }
88
104
}
89
105
90
106
impl ScopeEntry {
91
107
fn new ( pat : ast:: BindPat ) -> Option < ScopeEntry > {
92
- if pat. name ( ) . is_some ( ) {
93
- Some ( ScopeEntry {
94
- syntax : pat. syntax ( ) . owned ( ) ,
95
- } )
96
- } else {
97
- None
98
- }
99
- }
100
- pub fn name ( & self ) -> SmolStr {
101
- self . ast ( ) . name ( ) . unwrap ( ) . text ( )
108
+ let name = pat. name ( ) ?;
109
+ let res = ScopeEntry {
110
+ name : name. text ( ) ,
111
+ ptr : LocalSyntaxPtr :: new ( pat. syntax ( ) ) ,
112
+ } ;
113
+ Some ( res)
102
114
}
103
- pub fn ast ( & self ) -> ast :: BindPat {
104
- ast :: BindPat :: cast ( self . syntax . borrowed ( ) ) . unwrap ( )
115
+ pub ( crate ) fn name ( & self ) -> & SmolStr {
116
+ & self . name
105
117
}
106
- }
107
-
108
- impl fmt:: Debug for ScopeEntry {
109
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
110
- f. debug_struct ( "ScopeEntry" )
111
- . field ( "name" , & self . name ( ) )
112
- . field ( "syntax" , & self . syntax )
113
- . finish ( )
118
+ pub ( crate ) fn ptr ( & self ) -> LocalSyntaxPtr {
119
+ self . ptr
114
120
}
115
121
}
116
122
@@ -251,33 +257,28 @@ fn compute_expr_scopes(expr: ast::Expr, scopes: &mut FnScopes, scope: ScopeId) {
251
257
}
252
258
}
253
259
254
- #[ derive( Debug ) ]
255
- struct ScopeData {
256
- parent : Option < ScopeId > ,
257
- entries : Vec < ScopeEntry > ,
258
- }
259
-
260
260
pub fn resolve_local_name < ' a > (
261
261
name_ref : ast:: NameRef ,
262
262
scopes : & ' a FnScopes ,
263
263
) -> Option < & ' a ScopeEntry > {
264
- use rustc_hash:: FxHashSet ;
265
-
266
264
let mut shadowed = FxHashSet :: default ( ) ;
267
265
let ret = scopes
268
266
. scope_chain ( name_ref. syntax ( ) )
269
267
. flat_map ( |scope| scopes. entries ( scope) . iter ( ) )
270
268
. filter ( |entry| shadowed. insert ( entry. name ( ) ) )
271
- . filter ( |entry| entry. name ( ) == name_ref. text ( ) )
269
+ . filter ( |entry| entry. name ( ) == & name_ref. text ( ) )
272
270
. nth ( 0 ) ;
273
271
ret
274
272
}
275
273
276
274
#[ cfg( test) ]
277
275
mod tests {
278
- use super :: * ;
279
- use crate :: { find_node_at_offset, test_utils:: extract_offset} ;
280
276
use ra_syntax:: File ;
277
+ use test_utils:: extract_offset;
278
+ use ra_editor:: { find_node_at_offset} ;
279
+
280
+ use super :: * ;
281
+
281
282
282
283
fn do_check ( code : & str , expected : & [ & str ] ) {
283
284
let ( off, code) = extract_offset ( code) ;
@@ -384,14 +385,11 @@ mod tests {
384
385
385
386
let scopes = FnScopes :: new ( fn_def) ;
386
387
387
- let local_name = resolve_local_name ( name_ref, & scopes)
388
- . unwrap ( )
389
- . ast ( )
390
- . name ( )
391
- . unwrap ( ) ;
388
+ let local_name_entry = resolve_local_name ( name_ref, & scopes) . unwrap ( ) ;
389
+ let local_name = local_name_entry. ptr ( ) . resolve ( & file) ;
392
390
let expected_name =
393
391
find_node_at_offset :: < ast:: Name > ( file. syntax ( ) , expected_offset. into ( ) ) . unwrap ( ) ;
394
- assert_eq ! ( local_name. syntax ( ) . range( ) , expected_name. syntax( ) . range( ) ) ;
392
+ assert_eq ! ( local_name. range( ) , expected_name. syntax( ) . range( ) ) ;
395
393
}
396
394
397
395
#[ test]
0 commit comments