@@ -36,39 +36,60 @@ module Bluebird {
3636 * Provides classes for working with various Deferred implementations
3737 */
3838module Deferred {
39- private DataFlow:: SourceNode deferred ( ) {
40- (
41- exists ( Variable var |
39+ class DeferredClass extends DataFlow:: SourceNode {
40+ DeferredClass ( ) {
41+ exists ( Variable var |
4242 var .getName ( ) = "Deferred" and
43- ( var .getADeclaration ( ) instanceof LocalNamespaceDecl or var .getScope ( ) instanceof GlobalScope ) and
44- result = DataFlow:: valueNode ( var .getADefinition ( ) )
45- )
46- or
47- result .( DataFlow:: ParameterNode ) .getName ( ) = "Deferred"
48- or
43+ (
44+ var .getADeclaration ( ) instanceof LocalNamespaceDecl or
45+ var .getScope ( ) instanceof GlobalScope
46+ ) and
47+ this = DataFlow:: valueNode ( var .getADefinition ( ) )
48+ )
49+ or
50+ this .( DataFlow:: ParameterNode ) .getName ( ) = "Deferred"
51+ or
4952 exists ( Function f |
50- f .getName ( ) = "Deferred" and
51- result = DataFlow:: valueNode ( f )
53+ f .getName ( ) = "Deferred" and
54+ this = DataFlow:: valueNode ( f )
5255 )
5356 or
54- exists ( ClassDefinition c |
55- c .getName ( ) = "Deferred" and
56- result = DataFlow:: valueNode ( c )
57+ exists ( ClassDefinition c |
58+ c .getName ( ) = "Deferred" and
59+ this = DataFlow:: valueNode ( c )
5760 )
58- )
59- and
60- // Sanity check that it is a Deferred implementation
61- exists ( DataFlow:: NewNode instantiation |
62- instantiation = result .getAnInstantiation ( ) and
63- exists ( instantiation .getAMemberCall ( "resolve" ) )
64- )
61+ }
62+ }
63+
64+ class DeferredInstance extends DataFlow:: NewNode {
65+ DeferredClass deferredClass ;
66+
67+ DeferredInstance ( ) { this = deferredClass .getAnInstantiation ( ) }
68+
69+ private DataFlow:: SourceNode ref ( DataFlow:: TypeTracker t ) {
70+ t .start ( ) and
71+ result = this
72+ or
73+ exists ( DataFlow:: TypeTracker t2 | result = ref ( t2 ) .track ( t2 , t ) )
74+ }
75+
76+ DeferredClass getDeferredClass ( ) { result = deferredClass }
77+
78+ DataFlow:: CallNode getPromiseMemberCall ( string methodName ) {
79+ result = ref ( DataFlow:: TypeTracker:: end ( ) ) .getAMemberCall ( methodName )
80+ }
6581 }
6682
6783 /**
6884 * A promise object created by a Deferred constructor
6985 */
70- private class DeferredPromiseDefinition extends PromiseDefinition , DataFlow:: NewNode {
71- DeferredPromiseDefinition ( ) { this = deferred ( ) .getAnInstantiation ( ) }
86+ private class DeferredPromiseDefinition extends PromiseDefinition , DeferredInstance {
87+ DeferredPromiseDefinition ( ) {
88+ this = any ( DeferredClass c |
89+ exists ( any ( DeferredInstance i | i .getDeferredClass ( ) = c ) .getPromiseMemberCall ( "resolve" ) ) and
90+ exists ( any ( DeferredInstance i | i .getDeferredClass ( ) = c ) .getPromiseMemberCall ( "reject" ) )
91+ ) .getAnInstantiation ( )
92+ }
7293
7394 override DataFlow:: FunctionNode getExecutor ( ) { result = getCallback ( 0 ) }
7495 }
@@ -77,7 +98,9 @@ module Deferred {
7798 * A resolved promise created by a `new Deferred().resolve()` call.
7899 */
79100 class ResolvedDeferredPromiseDefinition extends ResolvedPromiseDefinition {
80- ResolvedDeferredPromiseDefinition ( ) { this = any ( DeferredPromiseDefinition def ) .getAMemberCall ( "resolve" ) }
101+ ResolvedDeferredPromiseDefinition ( ) {
102+ this = any ( DeferredPromiseDefinition def ) .getPromiseMemberCall ( "resolve" )
103+ }
81104
82105 override DataFlow:: Node getValue ( ) { result = getArgument ( 0 ) }
83106 }
0 commit comments