@@ -42,7 +42,7 @@ SourceNode getAnEnumeratedArrayElement(SourceNode array) {
4242 */
4343abstract class EnumeratedPropName extends DataFlow:: Node {
4444 /**
45- * Gets the object whose properties are being enumerated.
45+ * Gets the data flow node holding the object whose properties are being enumerated.
4646 *
4747 * For example, gets `src` in `for (var key in src)`.
4848 */
@@ -120,6 +120,52 @@ class EntriesEnumeratedPropName extends EnumeratedPropName {
120120 }
121121}
122122
123+ /**
124+ * Gets a function that enumerates object properties when invoked.
125+ *
126+ * Invocations takes the following form:
127+ * ```js
128+ * fn(obj, (value, key, o) => { ... })
129+ * ```
130+ */
131+ SourceNode propertyEnumerator ( ) {
132+ result = moduleImport ( "for-own" ) or
133+ result = moduleImport ( "for-in" ) or
134+ result = moduleMember ( "ramda" , "forEachObjIndexed" ) or
135+ result = LodashUnderscore:: member ( "forEach" ) or
136+ result = LodashUnderscore:: member ( "each" )
137+ }
138+
139+ /**
140+ * Property enumeration through a library function taking a callback.
141+ */
142+ class LibraryCallbackEnumeratedPropName extends EnumeratedPropName {
143+ CallNode call ;
144+ FunctionNode callback ;
145+
146+ LibraryCallbackEnumeratedPropName ( ) {
147+ call = propertyEnumerator ( ) .getACall ( ) and
148+ callback = call .getCallback ( 1 ) and
149+ this = callback .getParameter ( 1 )
150+ }
151+
152+ override Node getSourceObject ( ) {
153+ result = call .getArgument ( 0 )
154+ }
155+
156+ override SourceNode getASourceObjectRef ( ) {
157+ result = super .getASourceObjectRef ( )
158+ or
159+ result = callback .getParameter ( 2 )
160+ }
161+
162+ override SourceNode getASourceProp ( ) {
163+ result = super .getASourceProp ( )
164+ or
165+ result = callback .getParameter ( 0 )
166+ }
167+ }
168+
123169/**
124170 * Holds if the properties of `node` are enumerated locally.
125171 */
0 commit comments