@@ -2,6 +2,7 @@ use crate::binder::{self, Binder};
22use crate :: offsets:: token_from_offset;
33use crate :: resolve;
44use rowan:: { TextRange , TextSize } ;
5+ use smallvec:: { SmallVec , smallvec} ;
56use squawk_syntax:: {
67 SyntaxNodePtr ,
78 ast:: { self , AstNode } ,
@@ -10,7 +11,7 @@ use squawk_syntax::{
1011
1112pub fn find_references ( file : & ast:: SourceFile , offset : TextSize ) -> Vec < TextRange > {
1213 let binder = binder:: bind ( file) ;
13- let Some ( target ) = find_target ( file, offset, & binder) else {
14+ let Some ( targets ) = find_targets ( file, offset, & binder) else {
1415 return vec ! [ ] ;
1516 } ;
1617
@@ -21,14 +22,14 @@ pub fn find_references(file: &ast::SourceFile, offset: TextSize) -> Vec<TextRang
2122 match node {
2223 ast:: NameRef ( name_ref) => {
2324 if let Some ( found_refs) = resolve:: resolve_name_ref( & binder, & name_ref)
24- && found_refs. contains( & target )
25+ && found_refs. iter ( ) . any ( |ptr| targets . contains( ptr ) )
2526 {
2627 refs. push( name_ref. syntax( ) . text_range( ) ) ;
2728 }
2829 } ,
2930 ast:: Name ( name) => {
3031 let found = SyntaxNodePtr :: new( name. syntax( ) ) ;
31- if found == target {
32+ if targets . contains ( & found) {
3233 refs. push( name. syntax( ) . text_range( ) ) ;
3334 }
3435 } ,
@@ -41,20 +42,20 @@ pub fn find_references(file: &ast::SourceFile, offset: TextSize) -> Vec<TextRang
4142 refs
4243}
4344
44- fn find_target ( file : & ast:: SourceFile , offset : TextSize , binder : & Binder ) -> Option < SyntaxNodePtr > {
45+ fn find_targets (
46+ file : & ast:: SourceFile ,
47+ offset : TextSize ,
48+ binder : & Binder ,
49+ ) -> Option < SmallVec < [ SyntaxNodePtr ; 1 ] > > {
4550 let token = token_from_offset ( file, offset) ?;
4651 let parent = token. parent ( ) ?;
4752
4853 if let Some ( name) = ast:: Name :: cast ( parent. clone ( ) ) {
49- return Some ( SyntaxNodePtr :: new ( name. syntax ( ) ) ) ;
54+ return Some ( smallvec ! [ SyntaxNodePtr :: new( name. syntax( ) ) ] ) ;
5055 }
5156
5257 if let Some ( name_ref) = ast:: NameRef :: cast ( parent. clone ( ) ) {
53- // TODO: I think we want to return a list of targets so we can support cases like:
54- // select * from t join u using (id);
55- // ^ find refs
56- return resolve:: resolve_name_ref ( binder, & name_ref)
57- . and_then ( |ptrs| ptrs. into_iter ( ) . next ( ) ) ;
58+ return resolve:: resolve_name_ref ( binder, & name_ref) ;
5859 }
5960
6061 None
@@ -143,6 +144,26 @@ table users;
143144 " ) ;
144145 }
145146
147+ #[ test]
148+ fn join_using_column ( ) {
149+ assert_snapshot ! ( find_refs( "
150+ create table t(id int);
151+ create table u(id int);
152+ select * from t join u using (id$0);
153+ " ) , @r"
154+ ββΈ
155+ 2 β create table t(id int);
156+ β ββ 1. reference
157+ 3 β create table u(id int);
158+ β ββ 2. reference
159+ 4 β select * from t join u using (id);
160+ β β¬β¬
161+ β ββ
162+ β β0. query
163+ β°β΄ 3. reference
164+ " ) ;
165+ }
166+
146167 #[ test]
147168 fn find_from_definition ( ) {
148169 assert_snapshot ! ( find_refs( "
0 commit comments