@@ -107,7 +107,7 @@ import M2
107107private module Input3 implements InputSig3 {
108108 private import unified as Unified
109109
110- predicate cacheRevRef ( ) { exists ( resolveCallTarget ( _) ) implies any ( ) }
110+ predicate cacheRevRef ( ) { exists ( lookupMember ( _) ) implies any ( ) }
111111
112112 predicate inferTypeForDefaults = M3:: inferType / 2 ;
113113
@@ -478,6 +478,8 @@ private module Input3 implements InputSig3 {
478478
479479 abstract Expr getArgument ( int i ) ;
480480
481+ abstract int getNumberOfArguments ( ) ;
482+
481483 abstract Callable getTarget ( InvocationResolutionContext c ) ;
482484
483485 abstract Callable getATargetForTypeQualifierMatching ( ) ;
@@ -498,15 +500,28 @@ private module Input3 implements InputSig3 {
498500
499501 override Type getTypeArgument ( int pos , TypePath path ) { none ( ) }
500502
503+ override int getNumberOfArguments ( ) {
504+ exists ( Unified:: Callable target , boolean isFunctionExprInvoke |
505+ target = resolveCallTarget ( this , isFunctionExprInvoke ) and
506+ result = CallExpr .super .getNumberOfArguments ( ) + 1
507+ )
508+ }
509+
501510 override Expr getArgument ( int i ) {
502- i = 0 and
503- result = CallExpr .super .getCallee ( ) .( MemberAccessExpr ) .getBase ( )
504- or
505- result = CallExpr .super .getArgument ( i - 1 ) .getValue ( )
511+ exists ( Unified:: Callable target , boolean isFunctionExprInvoke |
512+ target = resolveCallTarget ( this , isFunctionExprInvoke )
513+ |
514+ i = 0 and
515+ if isFunctionExprInvoke = true
516+ then result = CallExpr .super .getCallee ( )
517+ else result = CallExpr .super .getCallee ( ) .( MemberAccessExpr ) .getBase ( )
518+ or
519+ result = CallExpr .super .getArgument ( i - 1 ) .getValue ( )
520+ )
506521 }
507522
508523 override Callable getTarget ( InvocationResolutionContext c ) {
509- result .getAstNode ( ) = resolveCallTarget ( this ) and
524+ result .getAstNode ( ) = resolveCallTarget ( this , _ ) and
510525 exists ( c )
511526 }
512527
@@ -517,11 +532,27 @@ private module Input3 implements InputSig3 {
517532 Invocation invocation , InvocationResolutionContext ctx , int i , TypePath path
518533 ) {
519534 exists ( ctx ) and
520- (
521- result = inferType ( invocation .getArgument ( i ) , path )
522- or
523- i = 0 and
524- result = getImplicitReceiverType ( invocation .( CallExpr ) .getCallee ( ) , path )
535+ exists ( boolean isFunctionExprInvoke |
536+ exists ( resolveCallTarget ( invocation , isFunctionExprInvoke ) )
537+ |
538+ if isFunctionExprInvoke = true
539+ then
540+ exists ( Type t | exists ( getInvokeTarget ( invocation , t ) ) |
541+ i = 0 and
542+ result = inferType ( invocation .( CallExpr ) .getCallee ( ) , path )
543+ or
544+ exists ( TypePath prefix , TypePath suffix , int j |
545+ functionInvokeSignature ( t , invocation .getNumberOfArguments ( ) - 1 , j , i , prefix ) and
546+ result = inferType ( invocation .getArgument ( j + 1 ) , suffix ) and
547+ path = prefix .append ( suffix )
548+ )
549+ )
550+ else (
551+ result = inferType ( invocation .getArgument ( i ) , path )
552+ or
553+ i = 0 and
554+ result = getImplicitReceiverType ( invocation .( CallExpr ) .getCallee ( ) , path )
555+ )
525556 )
526557 }
527558
@@ -543,29 +574,40 @@ private module Input3 implements InputSig3 {
543574 Parameter getParameter ( ) { result = TExplicitDeclaration ( this .getParam ( ) ) }
544575 }
545576
546- bindingset [ c ]
577+ pragma [ nomagic ]
547578 Type getClosureType ( Closure c ) { result = getFunctionExprType ( c .getAstNode ( ) ) }
548579
549580 pragma [ nomagic]
550581 TypePath getClosureParameterTypePath ( Parameter p ) {
551- exists ( FunctionExpr fe , int i |
582+ exists ( FunctionExpr fe , Type t , int i |
552583 p = TExplicitDeclaration ( fe .getParameter ( i ) ) and
553- result = getFunctionExprParameterTypePath ( fe , i )
584+ t = getFunctionExprType ( fe ) and
585+ result = getFunctionExprParameterTypePath ( t , fe .getNumberOfParameters ( ) , i )
554586 )
555587 }
556588
557- bindingset [ c ]
589+ pragma [ nomagic ]
558590 TypePath getClosureReturnTypePath ( Closure c ) {
559- result = getFunctionExprReturnTypePath ( c . getAstNode ( ) )
591+ result = getFunctionExprReturnTypePath ( getClosureType ( c ) )
560592 }
561593
562594 predicate stepLanguageSpecific ( AstNode n1 , TypePath prefix1 , AstNode n2 , TypePath prefix2 ) {
563- none ( )
595+ n1 = n2 .( Block ) .getLastStmt ( ) and
596+ prefix1 .isEmpty ( ) and
597+ prefix2 .isEmpty ( )
564598 }
565599
566600 Type inferTypeLanguageSpecific ( AstNode n , TypePath path ) {
567601 result = Plugin:: inferType ( n , path )
568602 or
603+ n instanceof BooleanLiteral and
604+ result instanceof BoolType and
605+ path .isEmpty ( )
606+ or
607+ n instanceof IntLiteral and
608+ result instanceof IntType and
609+ path .isEmpty ( )
610+ or
569611 exists ( ClassLikeDeclaration c |
570612 c = n .( SuperExpr ) .getEnclosingClass ( ) and
571613 result = c .getBaseType ( 0 ) .getType ( ) .( TypeMention ) .getTypeAt ( path )
@@ -602,18 +644,31 @@ Identifier lookupMember(MemberAccessExpr mae) {
602644 )
603645}
604646
605- Callable resolveCallTarget ( CallExpr ce ) {
647+ pragma [ nomagic]
648+ private Callable getInvokeTarget ( CallExpr ce , Type t ) {
649+ t = inferType ( ce .getCallee ( ) ) and
650+ result = getFunctionInvoke ( t )
651+ }
652+
653+ // Does not yet take overloading into account
654+ Callable resolveCallTarget ( CallExpr ce , boolean isFunctionExprInvoke ) {
606655 exists ( NameBinding b | b = getStaticBindingTarget ( ce .getCallee ( ) ) |
656+ // object creation
607657 exists ( ClassLikeDeclaration cls , ConstructorDeclaration init |
608658 cls .getNameNode ( ) = b and
609659 init = cls .getAMember ( ) and
610660 result = init
611661 )
612662 or
613663 result .( FunctionDeclaration ) .getNameNode ( ) = b
614- )
664+ ) and
665+ isFunctionExprInvoke = false
666+ or
667+ result .( Input3:: AstDeclaration:: Declaration ) .getNameNode ( ) = lookupMember ( ce .getCallee ( ) ) and
668+ isFunctionExprInvoke = false
615669 or
616- result .( Input3:: AstDeclaration:: Declaration ) .getNameNode ( ) = lookupMember ( ce .getCallee ( ) )
670+ result = getInvokeTarget ( ce , _) and
671+ isFunctionExprInvoke = true
617672}
618673
619674VariableDeclaration resolveFieldAccess ( MemberAccessExpr mae ) {
0 commit comments