@@ -14,14 +14,16 @@ export function createVueLanguageServiceProxy<T>(
1414 const proxyCache = new Map < string | symbol , Function | undefined > ( ) ;
1515 const getProxyMethod = ( target : ts . LanguageService , p : string | symbol ) : Function | undefined => {
1616 switch ( p ) {
17+ case 'findReferences' :
18+ return findReferences ( ts , language , languageService , asScriptId , target [ p ] ) ;
1719 case 'getCompletionsAtPosition' :
1820 return getCompletionsAtPosition ( ts , language , asScriptId , vueOptions , target [ p ] ) ;
1921 case 'getCompletionEntryDetails' :
2022 return getCompletionEntryDetails ( language , target [ p ] ) ;
2123 case 'getCodeFixesAtPosition' :
2224 return getCodeFixesAtPosition ( target [ p ] ) ;
2325 case 'getDefinitionAndBoundSpan' :
24- return getDefinitionAndBoundSpan ( language , asScriptId , target [ p ] ) ;
26+ return getDefinitionAndBoundSpan ( ts , language , asScriptId , target [ p ] ) ;
2527 }
2628 } ;
2729
@@ -42,6 +44,56 @@ export function createVueLanguageServiceProxy<T>(
4244 } ) ;
4345}
4446
47+ function findReferences < T > (
48+ ts : typeof import ( 'typescript' ) ,
49+ language : Language < T > ,
50+ languageService : ts . LanguageService ,
51+ asScriptId : ( fileName : string ) => T ,
52+ findReferences : ts . LanguageService [ 'findReferences' ] ,
53+ ) : ts . LanguageService [ 'findReferences' ] {
54+ return ( fileName , position ) => {
55+ const result = findReferences ( fileName , position ) ;
56+
57+ const sourceScript = language . scripts . get ( asScriptId ( fileName ) ) ;
58+ const root = sourceScript ?. generated ?. root ;
59+ if ( ! ( root instanceof VueVirtualCode ) ) {
60+ return result ;
61+ }
62+
63+ const { template } = root . sfc ;
64+ if ( template ) {
65+ const textSpan = {
66+ start : template . start + 1 ,
67+ length : 'template' . length ,
68+ } ;
69+ if ( position >= textSpan . start && position <= textSpan . start + textSpan . length ) {
70+ result ?. push ( {
71+ definition : {
72+ fileName,
73+ textSpan,
74+ kind : ts . ScriptElementKind . scriptElement ,
75+ name : fileName ,
76+ containerKind : ts . ScriptElementKind . unknown ,
77+ containerName : '' ,
78+ displayParts : [ ] ,
79+ } ,
80+ references : [
81+ {
82+ fileName,
83+ textSpan,
84+ isDefinition : true ,
85+ isWriteAccess : false ,
86+ } ,
87+ ...languageService . getFileReferences ( fileName ) ,
88+ ] ,
89+ } ) ;
90+ }
91+ }
92+
93+ return result ;
94+ } ;
95+ }
96+
4597function getCompletionsAtPosition < T > (
4698 ts : typeof import ( 'typescript' ) ,
4799 language : Language < T > ,
@@ -190,24 +242,42 @@ function getCodeFixesAtPosition(
190242}
191243
192244function getDefinitionAndBoundSpan < T > (
245+ ts : typeof import ( 'typescript' ) ,
193246 language : Language < T > ,
194247 asScriptId : ( fileName : string ) => T ,
195248 getDefinitionAndBoundSpan : ts . LanguageService [ 'getDefinitionAndBoundSpan' ] ,
196249) : ts . LanguageService [ 'getDefinitionAndBoundSpan' ] {
197250 return ( fileName , position ) => {
198251 const result = getDefinitionAndBoundSpan ( fileName , position ) ;
199- if ( ! result ?. definitions ?. length ) {
200- return result ;
201- }
202252
203253 const sourceScript = language . scripts . get ( asScriptId ( fileName ) ) ;
204- if ( ! sourceScript ?. generated ) {
254+ const root = sourceScript ?. generated ?. root ;
255+ if ( ! ( root instanceof VueVirtualCode ) ) {
205256 return result ;
206257 }
207258
208- const root = sourceScript . generated . root ;
209- if ( ! ( root instanceof VueVirtualCode ) ) {
210- return result ;
259+ if ( ! result ?. definitions ?. length ) {
260+ const { template } = root . sfc ;
261+ if ( template ) {
262+ const textSpan = {
263+ start : template . start + 1 ,
264+ length : 'template' . length ,
265+ } ;
266+ if ( position >= textSpan . start && position <= textSpan . start + textSpan . length ) {
267+ return {
268+ textSpan,
269+ definitions : [ {
270+ fileName,
271+ textSpan,
272+ kind : ts . ScriptElementKind . scriptElement ,
273+ name : fileName ,
274+ containerKind : ts . ScriptElementKind . unknown ,
275+ containerName : '' ,
276+ } ] ,
277+ } ;
278+ }
279+ }
280+ return ;
211281 }
212282
213283 if (
@@ -219,7 +289,6 @@ function getDefinitionAndBoundSpan<T>(
219289 }
220290
221291 const definitions = new Set < ts . DefinitionInfo > ( result . definitions ) ;
222- const skippedDefinitions : ts . DefinitionInfo [ ] = [ ] ;
223292
224293 // #5275
225294 if ( result . definitions . length >= 2 ) {
@@ -228,15 +297,11 @@ function getDefinitionAndBoundSpan<T>(
228297 root . sfc . content [ definition . textSpan . start - 1 ] === '@'
229298 || root . sfc . content . slice ( definition . textSpan . start - 5 , definition . textSpan . start ) === 'v-on:'
230299 ) {
231- skippedDefinitions . push ( definition ) ;
300+ definitions . delete ( definition ) ;
232301 }
233302 }
234303 }
235304
236- for ( const definition of skippedDefinitions ) {
237- definitions . delete ( definition ) ;
238- }
239-
240305 return {
241306 definitions : [ ...definitions ] ,
242307 textSpan : result . textSpan ,
0 commit comments