@@ -37,13 +37,13 @@ const AST_NODE_TYPES = Object.freeze({
3737} ) ;
3838
3939// Check if line number obtained from source map and the line number in hook node match
40- export function checkNodeLocation ( path : NodePath , line : number ) : boolean {
40+ function checkNodeLocation ( path : NodePath , line : number ) : boolean {
4141 const { start, end} = path . node . loc ;
4242 return line >= start . line && line <= end . line ;
4343}
4444
4545// Checks whether hookNode is a member of targetHookNode
46- export function filterMemberNodesOfTargetHook (
46+ function filterMemberNodesOfTargetHook (
4747 targetHookNode : NodePath ,
4848 hookNode : NodePath ,
4949) : boolean {
@@ -56,29 +56,15 @@ export function filterMemberNodesOfTargetHook(
5656}
5757
5858// Checks whether hook is the first member node of a state variable declaration node
59- export function filterMemberWithHookVariableName ( hook : NodePath ) : boolean {
59+ function filterMemberWithHookVariableName ( hook : NodePath ) : boolean {
6060 return (
6161 hook . node . init . property . type === AST_NODE_TYPES . NUMERIC_LITERAL &&
6262 hook . node . init . property . value === 0
6363 ) ;
6464}
6565
66- // Map the generated source line and column position to the original source and line.
67- export function mapCompiledLineNumberToOriginalLineNumber (
68- consumer : SourceConsumer ,
69- lineNumber : number ,
70- columnNumber : number ,
71- ) : number | null {
72- const { line} = consumer . originalPositionFor ( {
73- line : lineNumber ,
74- column : columnNumber ,
75- } ) ;
76-
77- return line ;
78- }
79-
8066// Returns all AST Nodes associated with 'potentialReactHookASTNode'
81- export function getFilteredHookASTNodes (
67+ function getFilteredHookASTNodes (
8268 potentialReactHookASTNode : NodePath ,
8369 potentialHooksFound : Array < NodePath > ,
8470 source : string ,
@@ -117,6 +103,47 @@ export function getFilteredHookASTNodes(
117103
118104// Returns Hook name
119105export function getHookName (
106+ hook : HooksNode ,
107+ originalSourceAST : mixed ,
108+ originalSourceCode : string ,
109+ originalSourceLineNumber : number ,
110+ ) : string | null {
111+ const hooksFromAST = getPotentialHookDeclarationsFromAST ( originalSourceAST ) ;
112+
113+ const potentialReactHookASTNode = hooksFromAST . find ( node => {
114+ const nodeLocationCheck = checkNodeLocation (
115+ node ,
116+ ( ( originalSourceLineNumber : any ) : number ) ,
117+ ) ;
118+ const hookDeclaractionCheck = isConfirmedHookDeclaration ( node ) ;
119+ return nodeLocationCheck && hookDeclaractionCheck ;
120+ } ) ;
121+
122+ if ( ! potentialReactHookASTNode ) {
123+ return null ;
124+ }
125+
126+ // nodesAssociatedWithReactHookASTNode could directly be used to obtain the hook variable name
127+ // depending on the type of potentialReactHookASTNode
128+ try {
129+ const nodesAssociatedWithReactHookASTNode = getFilteredHookASTNodes (
130+ potentialReactHookASTNode ,
131+ hooksFromAST ,
132+ originalSourceCode ,
133+ ) ;
134+
135+ return getHookNameFromNode (
136+ hook ,
137+ nodesAssociatedWithReactHookASTNode ,
138+ potentialReactHookASTNode ,
139+ ) ;
140+ } catch ( error ) {
141+ console . error ( error ) ;
142+ return null ;
143+ }
144+ }
145+
146+ function getHookNameFromNode (
120147 originalHook : HooksNode ,
121148 nodesAssociatedWithReactHookASTNode : NodePath [ ] ,
122149 potentialReactHookASTNode : NodePath ,
@@ -193,7 +220,7 @@ export function getHookName(
193220}
194221
195222// Extracts the variable name from hook node path
196- export function getHookVariableName (
223+ function getHookVariableName (
197224 hook : NodePath ,
198225 isCustomHook : boolean = false ,
199226) : string | null {
@@ -210,9 +237,7 @@ export function getHookVariableName(
210237 }
211238}
212239
213- export function getPotentialHookDeclarationsFromAST (
214- sourceAST : File ,
215- ) : NodePath [ ] {
240+ function getPotentialHookDeclarationsFromAST ( sourceAST : File ) : NodePath [ ] {
216241 const potentialHooksFound : NodePath [ ] = [ ] ;
217242 traverse ( sourceAST , {
218243 enter ( path ) {
@@ -225,7 +250,7 @@ export function getPotentialHookDeclarationsFromAST(
225250}
226251
227252// Check if 'path' contains declaration of the form const X = useState(0);
228- export function isConfirmedHookDeclaration ( path : NodePath ) : boolean {
253+ function isConfirmedHookDeclaration ( path : NodePath ) : boolean {
229254 const node = path . node . init ;
230255 if ( node . type !== AST_NODE_TYPES . CALL_EXPRESSION ) {
231256 return false ;
@@ -235,7 +260,7 @@ export function isConfirmedHookDeclaration(path: NodePath): boolean {
235260}
236261
237262// We consider hooks to be a hook name identifier or a member expression containing a hook name.
238- export function isHook ( node : Node ) : boolean {
263+ function isHook ( node : Node ) : boolean {
239264 if ( node . type === AST_NODE_TYPES . IDENTIFIER ) {
240265 return isHookName ( node . name ) ;
241266 } else if (
@@ -259,7 +284,7 @@ export function isHook(node: Node): boolean {
259284// Catch all identifiers that begin with "use"
260285// followed by an uppercase Latin character to exclude identifiers like "user".
261286// Copied from packages/eslint-plugin-react-hooks/src/RulesOfHooks
262- export function isHookName ( name : string ) : boolean {
287+ function isHookName ( name : string ) : boolean {
263288 return / ^ u s e [ A - Z 0 - 9 ] .* $ / . test ( name ) ;
264289}
265290
@@ -271,7 +296,7 @@ export function isNonDeclarativePrimitiveHook(hook: HooksNode) {
271296}
272297
273298// Check if the AST Node COULD be a React Hook
274- export function isPotentialHookDeclaration ( path : NodePath ) : boolean {
299+ function isPotentialHookDeclaration ( path : NodePath ) : boolean {
275300 // The array potentialHooksFound will contain all potential hook declaration cases we support
276301 const nodePathInit = path . node . init ;
277302 if ( nodePathInit != null ) {
@@ -305,7 +330,7 @@ export function isPotentialHookDeclaration(path: NodePath): boolean {
305330}
306331
307332/// Check whether 'node' is hook decalration of form useState(0); OR React.useState(0);
308- export function isReactFunction ( node : Node , functionName : string ) : boolean {
333+ function isReactFunction ( node : Node , functionName : string ) : boolean {
309334 return (
310335 node . name === functionName ||
311336 ( node . type === 'MemberExpression' &&
@@ -315,15 +340,15 @@ export function isReactFunction(node: Node, functionName: string): boolean {
315340}
316341
317342// Check if 'path' is either State or Reducer hook
318- export function isStateOrReducerHook ( path : NodePath ) : boolean {
343+ function isStateOrReducerHook ( path : NodePath ) : boolean {
319344 const callee = path . node . init . callee ;
320345 return (
321346 isReactFunction ( callee , 'useState' ) || isReactFunction ( callee , 'useReducer' )
322347 ) ;
323348}
324349
325350// Check whether hookNode of a declaration contains obvious variable name
326- export function nodeContainsHookVariableName ( hookNode : NodePath ) : boolean {
351+ function nodeContainsHookVariableName ( hookNode : NodePath ) : boolean {
327352 // We determine cases where variable names are obvious in declarations. Examples:
328353 // const [tick, setTick] = useState(1); OR const ref = useRef(null);
329354 // Here tick/ref are obvious hook variables in the hook declaration node itself
0 commit comments