@@ -68,19 +68,28 @@ module Typeahead {
6868 exists ( TypeaheadSource source |
6969 ref ( ) = source .getALocalSource ( ) or ref ( ) .getAMethodCall ( "ttAdapter" ) = source
7070 |
71- result = source .getSuccessor ( )
71+ result = source .getASuggestion ( )
7272 )
7373 }
7474 }
7575
76+ /**
77+ * An invocation of the `typeahead.js` library.
78+ */
79+ private class TypeaheadCall extends DataFlow:: CallNode {
80+ TypeaheadCall ( ) {
81+ // Matches `$(...).typeahead(..)`
82+ this = JQuery:: objectRef ( ) .getAMethodCall ( "typeahead" )
83+ }
84+ }
85+
7686 /**
7787 * A function that generates suggestions to typeahead.js.
7888 */
7989 class TypeaheadSuggestionFunction extends DataFlow:: FunctionNode {
80- DataFlow :: CallNode typeaheadCall ;
90+ TypeaheadCall typeaheadCall ;
8191
8292 TypeaheadSuggestionFunction ( ) {
83- typeaheadCall = JQuery:: objectRef ( ) .getAMethodCall ( "typeahead" ) and
8493 // Matches `$(...).typeahead({..}, { templates: { suggestion: <this> } })`.
8594 this = typeaheadCall
8695 .getOptionArgument ( 1 , "templates" )
@@ -93,25 +102,24 @@ module Typeahead {
93102 /**
94103 * Gets the call to typeahead.js where this suggestion function is used.
95104 */
96- DataFlow :: CallNode getTypeaheadCall ( ) { result = typeaheadCall }
105+ TypeaheadCall getTypeaheadCall ( ) { result = typeaheadCall }
97106 }
98107
99108 /**
100- * A `source` field in the typeahead.js library where there exists a successor that consumes the values from the `source` .
109+ * A `source` option for a typeahead.js plugin instance .
101110 */
102111 private class TypeaheadSource extends DataFlow:: ValueNode {
103- DataFlow:: Node successor ;
112+ TypeaheadCall typeaheadCall ;
113+
114+ TypeaheadSource ( ) { this = typeaheadCall .getOptionArgument ( 1 , "source" ) }
104115
105- TypeaheadSource ( ) {
106- // Matches `$(...).typeahead({..}, {source: <this>, templates: { suggestion: function(<successor> ) {} } })`.
107- exists ( TypeaheadSuggestionFunction suggestionFunction |
108- this = suggestionFunction .getTypeaheadCall ( ) . getOptionArgument ( 1 , "source" ) and
109- successor = suggestionFunction .getParameter ( 0 )
116+ /** Gets a node for a suggestion that this source motivates. */
117+ DataFlow :: Node getASuggestion ( ) {
118+ exists ( TypeaheadSuggestionFunction suggestionCallback |
119+ suggestionCallback .getTypeaheadCall ( ) = typeaheadCall and
120+ result = suggestionCallback .getParameter ( 0 )
110121 )
111122 }
112-
113- /** Gets the successor where values from the `source` field flow to. */
114- DataFlow:: Node getSuccessor ( ) { result = successor }
115123 }
116124
117125 /**
@@ -121,7 +129,7 @@ module Typeahead {
121129 override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
122130 // Matches `$(...).typeahead({..}, {source: function(q, cb) {..;cb(<pred>);..}, templates: { suggestion: function(<succ>) {} } })`.
123131 pred = this .getAFunctionValue ( ) .getParameter ( [ 1 .. 2 ] ) .getACall ( ) .getAnArgument ( ) and
124- succ = this .getSuccessor ( )
132+ succ = this .getASuggestion ( )
125133 }
126134 }
127135}
0 commit comments