This page documents the three related symbol-location features of the TypeScript language service: Find All References, Rename, and Document Highlights. All three features rely on the same underlying mechanism — resolving a symbol at a given position using the type checker, then searching the program's source files for occurrences of that symbol.
For information about the language service host and overall LanguageService interface, see 4 For go-to-definition (which also resolves a symbol but navigates to its declaration), see 4 generally. For how tsserver exposes these features over the wire, see 5.1
All three features are implemented inside the FindAllReferences module, defined in src/services/findAllReferences.ts Rename validation is handled by a companion Rename module. Both are consumed by the LanguageService implementation in src/services/services.ts
Data flow from editor request to result
Sources: src/services/findAllReferences.ts src/services/services.ts src/compiler/checker.ts src/compiler/program.ts
The LanguageService interface (in src/services/types.ts) exposes these methods:
| Method | Returns | Description |
|---|---|---|
getReferencesAtPosition(fileName, position) | ReferenceEntry[] | undefined | Flat list of all reference spans across files |
findReferences(fileName, position) | ReferencedSymbol[] | undefined | Grouped by symbol; includes definition info |
getDocumentHighlights(fileName, position, filesToSearch) | DocumentHighlights[] | undefined | Per-file highlight spans with read/write categorization |
getRenameInfo(fileName, position, preferences?) | RenameInfo | Validates whether a rename is possible |
findRenameLocations(fileName, position, findInStrings, findInComments, preferences?) | readonly RenameLocation[] | undefined | All spans that would be affected by a rename |
Sources: src/services/types.ts
Type hierarchy diagram
HighlightSpanKind is an enum with values none, definition, reference, and writtenReference. This lets editors render read and write occurrences differently.
Sources: src/services/types.ts src/services/findAllReferences.ts
FindAllReferencesThe FindAllReferences module in src/services/findAllReferences.ts provides the actual implementation. The LanguageService in src/services/services.ts delegates directly to it.
Two distinct results shapes are produced:
findReferencedSymbols — returns ReferencedSymbol[], grouping references by the defining symbol. Used by findReferences.getReferencesAtPosition — flattens the same result into ReferenceEntry[]. Used by getReferencesAtPosition.findRenameLocations — extracts RenameLocation[] from the same core search, filtered to only renameable spans.At the heart of every search is a call to checker.getSymbolAtLocation(node) on the node at the given source position. The module then determines which canonical symbol is being referenced by:
checker.getAliasedSymbol (for imports and re-exports).After the target symbol is identified, FindAllReferences iterates over every SourceFile in the Program. For each file it:
NameTable) to quickly skip files that cannot reference the symbol by name.forEachChild, inspecting each identifier.checker.getSymbolAtLocation and compares against the target symbol (accounting for aliases and merged declarations).This design avoids a full AST walk of every file when the symbol name does not appear.
A core sub-system is the ImportTracker, created by createImportTracker. It maps export symbols to all the places they are imported across the program. When the target symbol is an exported declaration, the tracker finds every ImportDeclaration or ImportEqualsDeclaration that pulls it in, then finds uses of those local aliases.
The flow is:
The functions getExportInfo, getImportOrExportSymbol, and findModuleReferences (all from the ts.FindAllReferences namespace) support this tracking.
Sources: src/services/findAllReferences.ts
| Case | Handling |
|---|---|
Shorthand property assignments ({ x }) | Both the property name and the value binding are recorded |
| String literals | Optionally searched when findInStrings is true (rename only) |
JSDoc @param tags | Parameter symbols in JSDoc are resolved to their host function parameters |
this keyword | Resolved to the containing class or object type |
| Private identifiers | Scoped to the containing class; cannot escape |
| Constructor signatures | References to the constructor are tracked alongside new expressions |
Re-exports (export { x } from ...) | Chased through via the import tracker |
| Dynamic imports | String literal arguments are compared when searching module-level references |
Sources: src/services/findAllReferences.ts
getRenameInfoBefore any rename edits are made, the editor calls getRenameInfo. This is implemented in the Rename module (imported in src/services/services.ts as Rename).
getRenameInfo returns either RenameInfoSuccess or RenameInfoFailure. The validation checks:
.d.ts file that the project does not own.import), fileToRename is populated so the editor can also rename the file on disk.getAdjustedRenameLocation (from src/services/utilities.ts) is called first to snap the position to the most meaningful token — for example, moving from the function keyword to the function name identifier.
findRenameLocationsOnce validated, findRenameLocations re-uses the same search machinery as findReferences. It calls into FindAllReferences with a mode flag that:
prefixText and suffixText to each RenameLocation when a span needs context preserved (e.g., renaming a shorthand property { x } needs to expand to { x: newName }, so suffixText: ": newName" is provided).findInStrings and findInComments options passed by the caller.RenameLocation extends DocumentSpan with these two optional text fields.
Sources: src/services/services.ts src/services/findAllReferences.ts src/services/utilities.ts
getDocumentHighlights is a scoped, single-file (or small set of files) variant of find references. It is called with a filesToSearch parameter limiting the search scope.
| Property | Find References | Document Highlights |
|---|---|---|
| Scope | All files in Program | Only filesToSearch |
| Result grouping | ReferencedSymbol[] (by symbol) | DocumentHighlights[] (by file) |
| Read/write distinction | isWriteAccess boolean | HighlightSpanKind (reference vs writtenReference) |
| Definition span | Included as a ReferenceEntry with isDefinition | Included with kind: "definition" |
| Primary use | "Find all references" UI | Cursor-position highlighting while editing |
HighlightSpanKindnone – no semantic highlight
definition – the declaration of the symbol
reference – a read-only reference
writtenReference – a write/assignment to the symbol
The distinction between reference and writtenReference lets editors highlight, for example, all assignments to a variable in a different color.
Sources: src/services/findAllReferences.ts src/services/types.ts
Sources: src/services/services.ts src/services/findAllReferences.ts src/services/utilities.ts src/compiler/checker.ts src/services/types.ts
The three features are exposed as tsserver commands (defined in src/server/protocol.ts):
| Command string | Protocol type | Language service method |
|---|---|---|
"references" | ReferencesRequest / ReferencesResponse | getReferencesAtPosition |
"rename" | RenameRequest / RenameResponse | getRenameInfo + findRenameLocations |
"documentHighlights" | DocumentHighlightsRequest / DocumentHighlightsResponse | getDocumentHighlights |
The Session class in src/server/session.ts handles these requests. It maps each request to the corresponding LanguageService call and converts the results from internal TypeScript types to the wire-format protocol types used in the JSON response.
findRenameLocations results are used by the tsserver rename command to produce both the info (from getRenameInfo) and the locs (from findRenameLocations) in a single response, avoiding a round trip.
Sources: src/server/protocol.ts src/server/session.ts
These features are tested primarily through the fourslash test framework (tests/cases/fourslash/fourslash.ts). The relevant fourslash verification APIs are:
verify.referencesOf(marker, references) — asserts which positions are returned by find referencesverify.rangesReferenceEachOther() — asserts that all marked ranges mutually reference each otherverify.renameLocations(startRanges, options) — asserts rename spans including prefix/suffix textverify.documentHighlights(markerList, expected) — asserts highlight spans and their kindsSources: tests/cases/fourslash/fourslash.ts
Refresh this wiki
This wiki was recently refreshed. Please wait 4 days to refresh again.