After much searching, I have finally discovered a solution.
Initially, I need to verify whether my Node is the second child of a PropertyAccessExpression
and if its grandparent is a CallExpression
.
From these criteria, I can determine that my node represents a call to a function.
Next, I must confirm if this function is a built-in JavaScript function. To do so, I must locate the Node's Definition (where the slice
function is defined in the example). This information can be found in the corresponding Symbol
related to the node.
Subsequently, I search for the file path where this function is declared. If the path matches /typescript\/lib/
, it indicates that it is a native TypeScript (or JavaScript) function.
I carry out these tasks using the impressive library ts-morph, though it is also possible to utilize the native ts
library.
/**
* Determines if a node represents a function or method call
* Example: a.slice(1)
* @param node // The node to be checked
*/
isFunctionCall(node: Node): boolean {
return node?.getParent()?.getParent()?.getKind() === SyntaxKind.CallExpression && isSecondSon(node);
}
/**
* Checks if a given node is the second child of its parent
* @param node // The node to be checked
*/
isSecondSon(node: Node): boolean {
if (!node?.getParent()) {
return false;
}
return node?.getChildIndex() === 2;
}
if (isFunctionCall(node)) {
const identifier = node as Identifier;
const definition = identifier.getDefinitions()?.[0];
const path = definition.getSourceFile().getFilePath();
return path.match(/typescript\/lib/);
}
I hope this explanation proves beneficial to someone in need.