6
6
'use strict' ;
7
7
8
8
const has = require ( 'has' ) ;
9
+ const includes = require ( 'array-includes' ) ;
9
10
const variableUtil = require ( '../util/variable' ) ;
10
11
const jsxUtil = require ( '../util/jsx' ) ;
11
12
const docsUrl = require ( '../util/docsUrl' ) ;
12
13
14
+
13
15
// ------------------------------------------------------------------------------
14
16
// Rule Definition
15
17
// ------------------------------------------------------------------------------
@@ -83,8 +85,8 @@ module.exports = {
83
85
} ) ;
84
86
}
85
87
86
- function findJSXElementOrFragment ( variables , name ) {
87
- function find ( refs ) {
88
+ function findJSXElementOrFragment ( variables , name , previousReferences ) {
89
+ function find ( refs , prevRefs ) {
88
90
let i = refs . length ;
89
91
90
92
while ( -- i >= 0 ) {
@@ -94,15 +96,26 @@ module.exports = {
94
96
return ( jsxUtil . isJSX ( writeExpr )
95
97
&& writeExpr )
96
98
|| ( ( writeExpr && writeExpr . type === 'Identifier' )
97
- && findJSXElementOrFragment ( variables , writeExpr . name ) ) ;
99
+ && findJSXElementOrFragment ( variables , writeExpr . name , prevRefs ) ) ;
98
100
}
99
101
}
100
102
101
103
return null ;
102
104
}
103
105
104
106
const variable = variableUtil . getVariable ( variables , name ) ;
105
- return variable && variable . references && find ( variable . references ) ;
107
+ if ( variable && variable . references ) {
108
+ const containDuplicates = previousReferences . some ( ( ref ) => includes ( variable . references , ref ) ) ;
109
+
110
+ // Prevent getting stuck in circular references
111
+ if ( containDuplicates ) {
112
+ return false ;
113
+ }
114
+
115
+ return find ( variable . references , previousReferences . concat ( variable . references ) ) ;
116
+ }
117
+
118
+ return false ;
106
119
}
107
120
108
121
function checkDescendant ( baseDepth , children ) {
@@ -141,7 +154,7 @@ module.exports = {
141
154
}
142
155
143
156
const variables = variableUtil . variablesInScope ( context ) ;
144
- const element = findJSXElementOrFragment ( variables , node . expression . name ) ;
157
+ const element = findJSXElementOrFragment ( variables , node . expression . name , [ ] ) ;
145
158
146
159
if ( element ) {
147
160
const baseDepth = getDepth ( node ) ;
0 commit comments