@@ -409,6 +409,29 @@ namespace ts.server {
409409 return outputs . filter ( o => o . references . length !== 0 ) ;
410410 }
411411
412+ function combineProjectOutputForFileReferences (
413+ projects : Projects ,
414+ defaultProject : Project ,
415+ fileName : string
416+ ) : readonly ReferenceEntry [ ] {
417+ const outputs : ReferenceEntry [ ] = [ ] ;
418+
419+ combineProjectOutputWorker (
420+ projects ,
421+ defaultProject ,
422+ /*initialLocation*/ undefined ,
423+ project => {
424+ for ( const referenceEntry of project . getLanguageService ( ) . getFileReferences ( fileName ) || emptyArray ) {
425+ if ( ! contains ( outputs , referenceEntry , documentSpansEqual ) ) {
426+ outputs . push ( referenceEntry ) ;
427+ }
428+ }
429+ } ,
430+ ) ;
431+
432+ return outputs ;
433+ }
434+
412435 interface ProjectAndLocation < TLocation extends DocumentPosition | undefined > {
413436 readonly project : Project ;
414437 readonly location : TLocation ;
@@ -1509,7 +1532,7 @@ namespace ts.server {
15091532 return arrayFrom ( map . values ( ) ) ;
15101533 }
15111534
1512- private getReferences ( args : protocol . FileLocationRequestArgs , simplifiedResult : boolean ) : protocol . ReferencesResponseBody | undefined | readonly ReferencedSymbol [ ] {
1535+ private getReferences ( args : protocol . FileLocationRequestArgs , simplifiedResult : boolean ) : protocol . ReferencesResponseBody | readonly ReferencedSymbol [ ] {
15131536 const file = toNormalizedPath ( args . file ) ;
15141537 const projects = this . getProjects ( args ) ;
15151538 const position = this . getPositionInFile ( args , file ) ;
@@ -1528,22 +1551,28 @@ namespace ts.server {
15281551 const nameSpan = nameInfo && nameInfo . textSpan ;
15291552 const symbolStartOffset = nameSpan ? scriptInfo . positionToLineOffset ( nameSpan . start ) . offset : 0 ;
15301553 const symbolName = nameSpan ? scriptInfo . getSnapshot ( ) . getText ( nameSpan . start , textSpanEnd ( nameSpan ) ) : "" ;
1531- const refs : readonly protocol . ReferencesResponseItem [ ] = flatMap ( references , referencedSymbol =>
1532- referencedSymbol . references . map ( ( { fileName, textSpan, contextSpan, isWriteAccess, isDefinition } ) : protocol . ReferencesResponseItem => {
1533- const scriptInfo = Debug . checkDefined ( this . projectService . getScriptInfo ( fileName ) ) ;
1534- const span = toProtocolTextSpanWithContext ( textSpan , contextSpan , scriptInfo ) ;
1535- const lineSpan = scriptInfo . lineToTextSpan ( span . start . line - 1 ) ;
1536- const lineText = scriptInfo . getSnapshot ( ) . getText ( lineSpan . start , textSpanEnd ( lineSpan ) ) . replace ( / \r | \n / g, "" ) ;
1537- return {
1538- file : fileName ,
1539- ...span ,
1540- lineText,
1541- isWriteAccess,
1542- isDefinition
1543- } ;
1544- } ) ) ;
1554+ const refs : readonly protocol . ReferencesResponseItem [ ] = flatMap ( references , referencedSymbol => {
1555+ return referencedSymbol . references . map ( entry => referenceEntryToReferencesResponseItem ( this . projectService , entry ) ) ;
1556+ } ) ;
15451557 return { refs, symbolName, symbolStartOffset, symbolDisplayString } ;
15461558 }
1559+
1560+ private getFileReferences ( args : protocol . FileRequestArgs , simplifiedResult : boolean ) : protocol . FileReferencesResponseBody | readonly ReferenceEntry [ ] {
1561+ const projects = this . getProjects ( args ) ;
1562+ const references = combineProjectOutputForFileReferences (
1563+ projects ,
1564+ this . getDefaultProject ( args ) ,
1565+ args . file ,
1566+ ) ;
1567+
1568+ if ( ! simplifiedResult ) return references ;
1569+ const refs = references . map ( entry => referenceEntryToReferencesResponseItem ( this . projectService , entry ) ) ;
1570+ return {
1571+ refs,
1572+ symbolName : `"${ args . file } "`
1573+ } ;
1574+ }
1575+
15471576 /**
15481577 * @param fileName is the name of the file to be opened
15491578 * @param fileContent is a version of the file content that is known to be more up to date than the one on disk
@@ -2639,6 +2668,12 @@ namespace ts.server {
26392668 [ CommandNames . GetSpanOfEnclosingComment ] : ( request : protocol . SpanOfEnclosingCommentRequest ) => {
26402669 return this . requiredResponse ( this . getSpanOfEnclosingComment ( request . arguments ) ) ;
26412670 } ,
2671+ [ CommandNames . FileReferences ] : ( request : protocol . FileReferencesRequest ) => {
2672+ return this . requiredResponse ( this . getFileReferences ( request . arguments , /*simplifiedResult*/ true ) ) ;
2673+ } ,
2674+ [ CommandNames . FileReferencesFull ] : ( request : protocol . FileReferencesRequest ) => {
2675+ return this . requiredResponse ( this . getFileReferences ( request . arguments , /*simplifiedResult*/ false ) ) ;
2676+ } ,
26422677 [ CommandNames . Format ] : ( request : protocol . FormatRequest ) => {
26432678 return this . requiredResponse ( this . getFormattingEditsForRange ( request . arguments ) ) ;
26442679 } ,
@@ -3068,4 +3103,18 @@ namespace ts.server {
30683103
30693104 return text ;
30703105 }
3106+
3107+ function referenceEntryToReferencesResponseItem ( projectService : ProjectService , { fileName, textSpan, contextSpan, isWriteAccess, isDefinition } : ReferenceEntry ) : protocol . ReferencesResponseItem {
3108+ const scriptInfo = Debug . checkDefined ( projectService . getScriptInfo ( fileName ) ) ;
3109+ const span = toProtocolTextSpanWithContext ( textSpan , contextSpan , scriptInfo ) ;
3110+ const lineSpan = scriptInfo . lineToTextSpan ( span . start . line - 1 ) ;
3111+ const lineText = scriptInfo . getSnapshot ( ) . getText ( lineSpan . start , textSpanEnd ( lineSpan ) ) . replace ( / \r | \n / g, "" ) ;
3112+ return {
3113+ file : fileName ,
3114+ ...span ,
3115+ lineText,
3116+ isWriteAccess,
3117+ isDefinition
3118+ } ;
3119+ }
30713120}
0 commit comments