Skip to content

Commit 9161e16

Browse files
committed
docs - Add "identifiers having same symbol" part
1 parent 9fd6827 commit 9161e16

File tree

1 file changed

+71
-3
lines changed

1 file changed

+71
-3
lines changed

translations/en/transformer-handbook.md

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ This document covers how to write a [Typescript](https://typescriptlang.org/) [T
4141
- [Transformation operations](#transformation-operations)
4242
- [Visiting](#visiting-1)
4343
- [Checking a node is a certain type](#checking-a-node-is-a-certain-type)
44-
- [Check if an identifier is referenced](#check-if-an-identifier-is-referenced)
44+
- [Check if two identifiers refer to the same symbol](#check-if-two-identifiers-refer-to-the-same-symbol)
4545
- [Find a specific parent](#find-a-specific-parent)
4646
- [Stopping traversal](#stopping-traversal)
4747
- [Manipulation](#manipulation)
@@ -879,9 +879,77 @@ const visitor = (node: ts.Node): ts.Node => {
879879
};
880880
```
881881

882-
#### Check if an identifier is referenced
882+
#### Check if two identifiers refer to the same symbol
883883

884-
> **TODO** - Is this possible?
884+
Identifiers are created by the parser and are always unique.
885+
Say, if you create a variable `foo` and use it in another line, it will create 2 separate identifiers with the same text `foo`.
886+
887+
Then, the linker runs through these identifiers and connects the identifiers referring to the same variable with a common symbol (while considering scope and shadowing). Think of symbols as what we intuitively think as variables.
888+
889+
So, to check if two identifiers refer to the same symbol - just get the symbols related to the identifier and check if they are the same (by reference).
890+
891+
Short example -
892+
893+
```ts
894+
const symbol1 = typeChecker.getSymbolAtLocation(node1);
895+
const symbol2 = typeChecker.getSymbolAtLocation(node2);
896+
897+
symbol1 === symbol2 // check by reference
898+
```
899+
900+
Full example -
901+
902+
This will log all repeating symbols.
903+
904+
```ts
905+
import * as ts from 'typescript';
906+
907+
const transformerProgram = (program: ts.Program) => {
908+
const typeChecker = program.getTypeChecker();
909+
910+
// Create array of found symbols
911+
const foundSymbols = new Array<ts.Symbol>();
912+
913+
const transformerFactory: ts.TransformerFactory<ts.SourceFile> = context => {
914+
return sourceFile => {
915+
const visitor = (node: ts.Node): ts.Node => {
916+
if (ts.isIdentifier(node)) {
917+
const relatedSymbol = typeChecker.getSymbolAtLocation(node);
918+
919+
// Check if set already contains same symbol - check by reference
920+
if (foundSymbols.includes(relatedSymbol)) {
921+
const foundIndex = foundSymbols.indexOf(relatedSymbol);
922+
console.log(
923+
`Found existing symbol at position = ${foundIndex} and name = "${relatedSymbol.name}"`
924+
);
925+
} else {
926+
// If not found, Add it to array
927+
foundSymbols.push(relatedSymbol);
928+
929+
console.log(
930+
`Found new symbol with name = "${
931+
relatedSymbol.name
932+
}". Added at positon = ${foundSymbols.length - 1}`
933+
);
934+
}
935+
936+
return node;
937+
}
938+
939+
return ts.visitEachChild(node, visitor, context);
940+
};
941+
942+
return ts.visitNode(sourceFile, visitor);
943+
};
944+
};
945+
946+
return transformerFactory;
947+
};
948+
949+
export default transformerProgram;
950+
```
951+
952+
> **Tip** - You can see the source for this at [/example-transformers/match-identifier-by-symbol](/example-transformers/match-identifier-by-symbol)
885953
886954
#### Find a specific parent
887955

0 commit comments

Comments
 (0)