@@ -123,7 +123,7 @@ import M2
123123private module Input3 implements InputSig3 {
124124 private import swift as Swift
125125
126- predicate cachedStageRevRef ( ) { none ( ) }
126+ predicate cachedStageRevRef ( ) { MethodCallResolution :: resolveMethodCall ( _ , _ ) implies any ( ) }
127127
128128 predicate inferType = M3:: inferType / 2 ;
129129
@@ -135,6 +135,8 @@ private module Input3 implements InputSig3 {
135135
136136 TypeMention getTypeAnnotation ( AstNode n ) {
137137 result .( ParamDeclTypeMention ) .getDecl ( ) = n
138+ or
139+ result .( TypedPatternTypeMention ) .getPattern ( ) = n
138140 // todo: more cases, like local variables with explicit type annotations and casts
139141 }
140142
@@ -264,9 +266,8 @@ private module Input3 implements InputSig3 {
264266 Callable getTargetCertain ( ) { none ( ) }
265267
266268 Callable getTarget ( CallResolutionContext ctx ) {
267- // todo: implement in QL
268- result = this .getStaticTarget ( ) and
269- exists ( ctx )
269+ exists ( ctx ) and
270+ result = getCallTarget ( this )
270271 }
271272 }
272273
@@ -278,8 +279,13 @@ private module Input3 implements InputSig3 {
278279 result = M3:: inferCallArgumentTypeTopDown ( _, _, _, n , path )
279280 }
280281
281- predicate inferStepSymmetric ( AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2 ) {
282- none ( )
282+ predicate inferStepSymmetric ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) {
283+ path1 .isEmpty ( ) and
284+ path2 .isEmpty ( ) and
285+ exists ( Variable v |
286+ n1 = v .getParentPattern ( ) and
287+ n2 = v .getDefiningNode ( )
288+ )
283289 }
284290
285291 predicate inferStep ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) {
@@ -318,6 +324,68 @@ predicate inferType = M3::inferType/2;
318324
319325predicate inferTypeCertain = M3:: inferTypeCertain / 2 ;
320326
327+ private module MethodCallResolution {
328+ private class MethodCall extends MethodCallExpr {
329+ pragma [ nomagic]
330+ predicate hasInfo ( string name , int arity ) {
331+ name =
332+ this .getFunction ( )
333+ .( MethodLookupExpr )
334+ .getMethodRef ( )
335+ .( DeclRefExpr )
336+ .getDecl ( )
337+ .( Method )
338+ .getName ( ) and
339+ arity = this .getNumberOfArguments ( )
340+ }
341+
342+ Type getTypeAt ( TypePath path ) { result = inferType ( this .getQualifier ( ) , path ) }
343+ }
344+
345+ pragma [ nomagic]
346+ private predicate methodInfo ( Method m , string name , int arity , ParamDeclTypeMention selfType ) {
347+ name = m .getName ( ) and
348+ arity = m .getNumberOfParams ( ) and
349+ selfType .getDecl ( ) = m .getSelfParam ( )
350+ }
351+
352+ private module MethodCallQualifierSatisfiesSelfTypeInput implements
353+ SatisfiesConstraintInputSig< MethodCall , TypeMention >
354+ {
355+ pragma [ nomagic]
356+ predicate relevantConstraint ( MethodCall call , TypeMention constraint ) {
357+ exists ( string name , int arity |
358+ call .hasInfo ( name , arity ) and
359+ methodInfo ( _, name , arity , constraint )
360+ )
361+ }
362+ }
363+
364+ private module MethodCallQualifierSatisfiesSelfType =
365+ SatisfiesConstraint< MethodCall , TypeMention , MethodCallQualifierSatisfiesSelfTypeInput > ;
366+
367+ cached
368+ predicate resolveMethodCall ( MethodCallExpr call , Method m ) {
369+ M3:: CachedStage:: ref ( ) and
370+ exists ( ParamDeclTypeMention selfType |
371+ MethodCallQualifierSatisfiesSelfType:: satisfiesConstraint ( call , selfType , _, _) and
372+ methodInfo ( m , _, _, selfType )
373+ )
374+ }
375+ }
376+
377+ Callable getCallTarget ( CallExpr call ) {
378+ MethodCallResolution:: resolveMethodCall ( call , result )
379+ or
380+ // todo: implement in QL
381+ result = call .getStaticTarget ( ) and
382+ (
383+ not call instanceof MethodCallExpr
384+ or
385+ result instanceof Initializer
386+ )
387+ }
388+
321389module Consistency {
322390 import M2:: Consistency
323391}
0 commit comments