@@ -62,17 +62,42 @@ private module Dispatch {
6262 cached
6363 Method viableImpl_v3 ( MethodAccess ma ) { result = DispatchFlow:: viableImpl_out ( ma ) }
6464
65- private predicate qualType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
66- exprTypeFlow ( ma .getQualifier ( ) , t , exact )
67- }
68-
6965 /**
7066 * INTERNAL: Use `viableImpl` instead.
7167 *
7268 * Gets a viable implementation of the method called in the given method access.
7369 */
7470 cached
7571 Method viableImpl_v2 ( MethodAccess ma ) {
72+ result = viableImpl_v2_cand ( pragma [ only_bind_into ] ( ma ) ) and
73+ exists ( Method def , RefType t , boolean exact |
74+ qualUnionType ( pragma [ only_bind_into ] ( ma ) , pragma [ only_bind_into ] ( t ) ,
75+ pragma [ only_bind_into ] ( exact ) ) and
76+ def = ma .getMethod ( ) .getSourceDeclaration ( )
77+ |
78+ exact = true and result = exactMethodImpl ( def , t .getSourceDeclaration ( ) )
79+ or
80+ exact = false and
81+ exists ( RefType t2 |
82+ result = viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
83+ not Unification_v2:: failsUnification ( t , t2 )
84+ )
85+ )
86+ or
87+ result = viableImpl_v2_cand ( ma ) and
88+ not qualUnionType ( ma , _, _)
89+ }
90+
91+ private predicate qualUnionType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
92+ exprUnionTypeFlow ( ma .getQualifier ( ) , t , exact )
93+ }
94+
95+ private predicate unificationTargetLeft_v2 ( ParameterizedType t1 ) { qualUnionType ( _, t1 , _) }
96+
97+ private module Unification_v2 =
98+ MkUnification< unificationTargetLeft_v2 / 1 , unificationTargetRight / 1 > ;
99+
100+ private Method viableImpl_v2_cand ( MethodAccess ma ) {
76101 result = viableImpl_v1 ( ma ) and
77102 (
78103 exists ( Method def , RefType t , boolean exact |
@@ -84,18 +109,22 @@ private module Dispatch {
84109 exact = false and
85110 exists ( RefType t2 |
86111 result = viableMethodImpl ( def , t .getSourceDeclaration ( ) , t2 ) and
87- not Unification_v2 :: failsUnification ( t , t2 )
112+ not Unification_v2_cand :: failsUnification ( t , t2 )
88113 )
89114 )
90115 or
91116 not qualType ( ma , _, _)
92117 )
93118 }
94119
95- private predicate unificationTargetLeft_v2 ( ParameterizedType t1 ) { qualType ( _, t1 , _) }
120+ private predicate qualType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
121+ exprTypeFlow ( ma .getQualifier ( ) , t , exact )
122+ }
123+
124+ private predicate unificationTargetLeft_v2_cand ( ParameterizedType t1 ) { qualType ( _, t1 , _) }
96125
97- private module Unification_v2 =
98- MkUnification< unificationTargetLeft_v2 / 1 , unificationTargetRight / 1 > ;
126+ private module Unification_v2_cand =
127+ MkUnification< unificationTargetLeft_v2_cand / 1 , unificationTargetRight / 1 > ;
99128
100129 /**
101130 * INTERNAL: Use `viableImpl` instead.
@@ -161,9 +190,8 @@ private module Dispatch {
161190 }
162191
163192 private predicate hasQualifierType ( VirtualMethodAccess ma , RefType t , boolean exact ) {
164- exists ( Expr src | src = variableTrack ( ma .getQualifier ( ) ) |
165- // If we have a qualifier, then we track it through variable assignments
166- // and take the type of the assigned value.
193+ exists ( Expr src | src = ma .getQualifier ( ) |
194+ // If we have a qualifier, then we take its type.
167195 exists ( RefType srctype | srctype = getPreciseType ( src ) |
168196 exists ( BoundedType bd | bd = srctype |
169197 t = bd .getAnUltimateUpperBoundType ( )
@@ -224,34 +252,7 @@ private module Dispatch {
224252
225253import Dispatch
226254
227- private Expr variableTrackStep ( Expr use ) {
228- exists ( Variable v |
229- pragma [ only_bind_out ] ( use ) = v .getAnAccess ( ) and
230- use .getType ( ) instanceof RefType and
231- not result instanceof NullLiteral and
232- not v .( LocalVariableDecl ) .getDeclExpr ( ) .hasImplicitInit ( )
233- |
234- not v instanceof Parameter and
235- result = v .getAnAssignedValue ( )
236- or
237- exists ( Parameter p | p = v and p .getCallable ( ) .isPrivate ( ) |
238- result = p .getAnAssignedValue ( ) or
239- result = p .getAnArgument ( )
240- )
241- )
242- }
243-
244- private Expr variableTrackPath ( Expr use ) {
245- result = variableTrackStep * ( use ) and
246- not exists ( variableTrackStep ( result ) )
247- }
248-
249255/**
250- * Gets an expression by tracking `use` backwards through variable assignments .
256+ * DEPRECATED: Use `TypeFlow` instead .
251257 */
252- pragma [ inline]
253- Expr variableTrack ( Expr use ) {
254- result = variableTrackPath ( use )
255- or
256- not exists ( variableTrackPath ( use ) ) and result = use
257- }
258+ deprecated Expr variableTrack ( Expr use ) { result = use }
0 commit comments