Find second hand references
- Dominant language
- TypeScript
- Stars
- 6.2k
- Forks
- 238
- Avg merge
- 2m
- Merged PRs (30d)
- 1
Description
**Is your feature request related to a problem? Please describe.**
The function `findReferencesAsNodes` doesn't always find all the references of a node. See this example:
```
var WS = (function ($) { // WS for Workspace
var f1 = function(){
return true;
}
var f2 = function(){
return true;
}
return {
f1_ref : f1,
f2_ref :f2,
}
})(jQuery);
function test(){
WS.f1_ref();
return WS.f1_ref();
}
```
In this code, the anonymous function f1 is declared in the line 2 of the code and referenced directly in the line 11 ( `f1_ref : f1 `). But the same anonymous function is also referenced in the lines 17 (`WS.f1_ref();`) and 18 ( `return WS.f1_ref();`).
When calling `project.getLanguageService().findReferencesAsNodes(node)` on the VariableDeclaration node corresponding to the anonymous f1, only the direct reference in line 11 gets returned.
This might be an omission or an intended behavior since the non-returned references of the anonymous function are technically references of references... I'm not sure.
**Describe the solution you'd like**
A function capable of getting all references, including the one that were not retrieved in my example would be nice : find**All**ReferencesAsNodes ?
**Describe alternatives you've considered**
I have a found a workaround for this particular case: for each reference found, I check if its parent node is a propertyAssignmentNode. If it indeed is the case, then I retrieve the left element from the property assignment and go look for its own references.
```
let propertyAssignmentNode = refNode.getFirstAncestorByKind(tsm.SyntaxKind.PropertyAssignment);
if (propertyAssignmentNode){
let leftPropertyAssignment = propertyAssignmentNode.getNameNode();
project.getLanguageService().findReferencesAsNodes(leftPropertyAssignment).forEach((otherRef)=>{
console.log("\t\t - Other reference found here: " + otherRef.getStart() + " line : " + otherRef.getSourceFile().getLineAndColumnAtPos(otherRef.getStart()).line);
});
}
```
This solution is not optimal, depending on the source code their might be cases I didn't considered. For instance, there might a distant parent propertyAssignmentNode that would break my reference test...
For more clarity, you can find here a simple script of mine that is able to retrieve all anonymous functions references from a srouce code and log their positions in the console :
```
import * as ts from "typescript";
import * as fs from "fs";
import * as tsm from "ts-morph";
function visit(node) {
if (tsm.Node.isVariableDeclaration(node)) { //anonymous function are function expression declared though a variable
if (node.getType().getText()[0]=="("){ //anonymous function var type does always start with "(", ex: "() => ...", there might be a better way to check this
console.log("A VariableDeclaration corresponding to an anonymous function was found: " + node.getName())
let functionExpressionNode = node.getFirstAncestorByKind(tsm.SyntaxKind.FunctionExpression); //recovering the expression function node :
project.getLanguageService().findReferencesAsNodes(node).forEach((refNode)=>{ //going through all references
console.log("\t - Reference found here: " + refNode.getStart());
let propertyAssignmentNode = refNode.getFirstAncestorByKind(tsm.SyntaxKind.PropertyAssignment);
if (propertyAssignmentNode){
//finding the second had refs
let leftPropertyAssignment = propertyAssignmentNode.getNameNode();
project.getLanguageService().findReferencesAsNodes(leftPropertyAssignment).forEach((otherRef)=>{
console.log("\t\t - Other reference found here: " + otherRef.getStart() + " line : " + otherRef.getSourceFile().getLineAndColumnAtPos(otherRef.getStart()).line);
});
}
});
}
}
node.getChildren().forEach((child) => visit(child));
}
var project = new tsm.Project();
project.addSourceFileAtPath("test.ts"); //path of the code to parse
project.getSourceFiles().forEach((sourceFile) => {
sourceFile.getChildren().forEach((child) => visit(child)); //visit every child
});
```
(To launch this script through cmd, enter: tsc script.ts --m commonjs && node script.js)
Contributor guide
Assessment
This issue has not been assessed yet.