11use crate :: binder;
22use crate :: builtins:: parse_builtins;
3+ use crate :: classify:: { NameRefClass , classify_def_node} ;
34use crate :: db:: { File , parse} ;
45use crate :: offsets:: token_from_offset;
56use crate :: resolve;
@@ -31,7 +32,10 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
3132 if let Some ( case_expr) = ast:: CaseExpr :: cast ( parent)
3233 && let Some ( case_token) = case_expr. case_token ( )
3334 {
34- return smallvec ! [ Location :: range( case_token. text_range( ) ) ] ;
35+ return smallvec ! [ Location :: current(
36+ case_token. text_range( ) ,
37+ LocationKind :: CaseExpr
38+ ) ] ;
3539 }
3640 }
3741 }
@@ -40,26 +44,28 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
4044 if ast:: Commit :: can_cast ( parent. kind ( ) )
4145 && let Some ( begin_range) = find_preceding_begin ( source_file, token. text_range ( ) . start ( ) )
4246 {
43- return smallvec ! [ Location :: range ( begin_range) ] ;
47+ return smallvec ! [ Location :: current ( begin_range, LocationKind :: CommitBegin ) ] ;
4448 }
4549
4650 // goto def on ROLLBACK -> BEGIN/START TRANSACTION
4751 if ast:: Rollback :: can_cast ( parent. kind ( ) )
4852 && let Some ( begin_range) = find_preceding_begin ( source_file, token. text_range ( ) . start ( ) )
4953 {
50- return smallvec ! [ Location :: range ( begin_range) ] ;
54+ return smallvec ! [ Location :: current ( begin_range, LocationKind :: CommitBegin ) ] ;
5155 }
5256
5357 // goto def on BEGIN/START TRANSACTION -> COMMIT or ROLLBACK
5458 if ast:: Begin :: can_cast ( parent. kind ( ) )
5559 && let Some ( end_range) =
5660 find_following_commit_or_rollback ( source_file, token. text_range ( ) . end ( ) )
5761 {
58- return smallvec ! [ Location :: range ( end_range) ] ;
62+ return smallvec ! [ Location :: current ( end_range, LocationKind :: CommitEnd ) ] ;
5963 }
6064
61- if let Some ( name) = ast:: Name :: cast ( parent. clone ( ) ) {
62- return smallvec ! [ Location :: range( name. syntax( ) . text_range( ) ) ] ;
65+ if let Some ( name) = ast:: Name :: cast ( parent. clone ( ) )
66+ && let Some ( kind) = classify_def_node ( name. syntax ( ) ) . map ( LocationKind :: from)
67+ {
68+ return smallvec ! [ Location :: current( name. syntax( ) . text_range( ) , kind) ] ;
6369 }
6470
6571 if let Some ( name_ref) = ast:: NameRef :: cast ( parent. clone ( ) ) {
@@ -71,13 +77,14 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
7177 // TODO: we should salsa this
7278 let binder_output = binder:: bind ( file) ;
7379 let root = file. syntax ( ) ;
74- if let Some ( ptrs) = resolve:: resolve_name_ref_ptrs ( & binder_output, root, & name_ref) {
80+ if let Some ( ( ptrs, kind ) ) = resolve:: resolve_name_ref ( & binder_output, root, & name_ref) {
7581 let ranges = ptrs
7682 . iter ( )
7783 . map ( |ptr| ptr. to_node ( file. syntax ( ) ) . text_range ( ) )
7884 . map ( |range| Location {
7985 file : file_id,
8086 range,
87+ kind,
8188 } )
8289 . collect ( ) ;
8390 return ranges;
@@ -106,6 +113,7 @@ pub fn goto_definition(db: &dyn Db, file: File, offset: TextSize) -> SmallVec<[L
106113 return smallvec ! [ Location {
107114 file: file_id,
108115 range: ptr. to_node( file. syntax( ) ) . text_range( ) ,
116+ kind: LocationKind :: Type ,
109117 } ] ;
110118 }
111119 }
@@ -120,17 +128,111 @@ pub enum FileId {
120128 Builtins ,
121129}
122130
131+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
132+ pub enum LocationKind {
133+ Aggregate ,
134+ CaseExpr ,
135+ Channel ,
136+ Column ,
137+ CommitBegin ,
138+ CommitEnd ,
139+ Cursor ,
140+ Database ,
141+ EventTrigger ,
142+ Extension ,
143+ Function ,
144+ Index ,
145+ NamedArgParameter ,
146+ Policy ,
147+ PreparedStatement ,
148+ Procedure ,
149+ Role ,
150+ Schema ,
151+ Sequence ,
152+ Server ,
153+ Table ,
154+ Tablespace ,
155+ Trigger ,
156+ Type ,
157+ View ,
158+ Window ,
159+ }
160+
123161#[ derive( Debug , Clone , PartialEq , Eq ) ]
124162pub struct Location {
125163 pub file : FileId ,
126164 pub range : TextRange ,
165+ pub kind : LocationKind ,
127166}
128167
129168impl Location {
130- fn range ( range : TextRange ) -> Location {
169+ fn current ( range : TextRange , kind : LocationKind ) -> Location {
131170 Location {
132171 file : FileId :: Current ,
133172 range,
173+ kind,
174+ }
175+ }
176+ }
177+
178+ impl From < NameRefClass > for LocationKind {
179+ fn from ( class : NameRefClass ) -> Self {
180+ match class {
181+ NameRefClass :: Aggregate => LocationKind :: Aggregate ,
182+ NameRefClass :: Channel => LocationKind :: Channel ,
183+ NameRefClass :: Cursor => LocationKind :: Cursor ,
184+ NameRefClass :: Database => LocationKind :: Database ,
185+ NameRefClass :: EventTrigger => LocationKind :: EventTrigger ,
186+ NameRefClass :: Extension => LocationKind :: Extension ,
187+ NameRefClass :: Index => LocationKind :: Index ,
188+ NameRefClass :: NamedArgParameter => LocationKind :: NamedArgParameter ,
189+ NameRefClass :: Policy => LocationKind :: Policy ,
190+ NameRefClass :: PreparedStatement => LocationKind :: PreparedStatement ,
191+ NameRefClass :: Role => LocationKind :: Role ,
192+ NameRefClass :: Schema => LocationKind :: Schema ,
193+ NameRefClass :: Sequence => LocationKind :: Sequence ,
194+ NameRefClass :: Server => LocationKind :: Server ,
195+ NameRefClass :: Tablespace => LocationKind :: Tablespace ,
196+ NameRefClass :: Trigger => LocationKind :: Trigger ,
197+ NameRefClass :: Type => LocationKind :: Type ,
198+ NameRefClass :: View => LocationKind :: View ,
199+ NameRefClass :: Window => LocationKind :: Window ,
200+
201+ NameRefClass :: CallProcedure | NameRefClass :: Procedure | NameRefClass :: ProcedureCall => {
202+ LocationKind :: Procedure
203+ }
204+
205+ NameRefClass :: Function
206+ | NameRefClass :: FunctionCall
207+ | NameRefClass :: FunctionName
208+ | NameRefClass :: Routine
209+ | NameRefClass :: SelectFunctionCall => LocationKind :: Function ,
210+
211+ NameRefClass :: AlterColumn
212+ | NameRefClass :: CompositeTypeField
213+ | NameRefClass :: ConstraintColumn
214+ | NameRefClass :: CreateIndexColumn
215+ | NameRefClass :: DeleteColumn
216+ | NameRefClass :: ForeignKeyColumn
217+ | NameRefClass :: InsertColumn
218+ | NameRefClass :: JoinUsingColumn
219+ | NameRefClass :: MergeColumn
220+ | NameRefClass :: PolicyColumn
221+ | NameRefClass :: QualifiedColumn
222+ | NameRefClass :: SelectColumn
223+ | NameRefClass :: SelectQualifiedColumn
224+ | NameRefClass :: UpdateColumn => LocationKind :: Column ,
225+
226+ NameRefClass :: DeleteQualifiedColumnTable
227+ | NameRefClass :: ForeignKeyTable
228+ | NameRefClass :: FromTable
229+ | NameRefClass :: InsertQualifiedColumnTable
230+ | NameRefClass :: LikeTable
231+ | NameRefClass :: MergeQualifiedColumnTable
232+ | NameRefClass :: PolicyQualifiedColumnTable
233+ | NameRefClass :: SelectQualifiedColumnTable
234+ | NameRefClass :: Table
235+ | NameRefClass :: UpdateQualifiedColumnTable => LocationKind :: Table ,
134236 }
135237 }
136238}
0 commit comments