File tree Expand file tree Collapse file tree
test/library-tests/MemberRefExpr Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1225,6 +1225,27 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
12251225 */
12261226 override Method asMethod ( ) { result = getAnonymousClass ( ) .getAMethod ( ) }
12271227
1228+ /**
1229+ * Gets the receiver type whose member this expression refers to. The result might not be
1230+ * the type which actually declares the member (makes a difference for inherited non-overridden
1231+ * methods).
1232+ */
1233+ RefType getReceiverType ( ) {
1234+ exists ( Stmt stmt , Expr resultExpr |
1235+ stmt = asMethod ( ) .getBody ( ) .( SingletonBlock ) .getStmt ( ) and
1236+ (
1237+ resultExpr = stmt .( ReturnStmt ) .getResult ( )
1238+ or
1239+ // Note: Currently never an ExprStmt, but might change once https://github.com/github/codeql/issues/3605 is fixed
1240+ resultExpr = stmt .( ExprStmt ) .getExpr ( )
1241+ )
1242+ |
1243+ result = resultExpr .( MethodAccess ) .getReceiverType ( ) or
1244+ result = resultExpr .( ClassInstanceExpr ) .getConstructedType ( ) or
1245+ result = resultExpr .( ArrayCreationExpr ) .getType ( )
1246+ )
1247+ }
1248+
12281249 /**
12291250 * Gets the method or constructor referenced by this member reference expression.
12301251 */
Original file line number Diff line number Diff line change 1+ | Test.java:24:26:24:51 | ...::... | Inner<>.Inner<> | Test$Generic$Inner.class:0:0:0:0 | Inner<> |
2+ | Test.java:38:29:38:42 | ...::... | Object.toString | Test.java:1:7:1:10 | Test |
3+ | Test.java:39:29:39:42 | ...::... | Object.hashCode | Test.java:1:7:1:10 | Test |
4+ | Test.java:40:29:40:39 | ...::... | Object.clone | Test.java:1:7:1:10 | Test |
5+ | Test.java:41:40:41:64 | ...::... | Object.toString | Test$Generic.class:0:0:0:0 | Generic<String> |
6+ | Test.java:43:23:43:36 | ...::... | Object.toString | Test.java:1:7:1:10 | Test |
7+ | Test.java:44:23:44:36 | ...::... | Object.hashCode | Test.java:1:7:1:10 | Test |
8+ | Test.java:45:23:45:33 | ...::... | Object.clone | Test.java:1:7:1:10 | Test |
9+ | Test.java:48:22:48:35 | ...::... | Object.toString | Test.java:1:7:1:10 | Test |
10+ | Test.java:51:13:51:21 | ...::... | Test.Test | Test.java:1:7:1:10 | Test |
11+ | Test.java:52:13:52:32 | ...::... | Generic<String>.Generic<String> | Test$Generic.class:0:0:0:0 | Generic<String> |
12+ | Test.java:56:13:56:22 | ...::... | | file://:0:0:0:0 | int[] |
13+ | Test.java:57:13:57:26 | ...::... | | file://:0:0:0:0 | Generic<>[] |
14+ | Test.java:61:31:61:47 | ...::... | Test.doSomething | Test.java:1:7:1:10 | Test |
Original file line number Diff line number Diff line change 1+ import java
2+
3+ string getReferencedCallable ( MemberRefExpr e ) {
4+ if exists ( e .getReferencedCallable ( ) )
5+ then result = e .getReferencedCallable ( ) .getQualifiedName ( )
6+ else result = ""
7+ }
8+
9+ from MemberRefExpr e
10+ select e , getReferencedCallable ( e ) , e .getReceiverType ( )
Original file line number Diff line number Diff line change 1+ class Test {
2+ interface Function <T > {
3+ Object apply (T o ) throws Exception ;
4+ }
5+
6+ interface IntFunction {
7+ Object apply (int i );
8+ }
9+
10+ interface Supplier {
11+ Object get () throws Exception ;
12+ }
13+
14+ public Test () { }
15+
16+ static class Generic <T > {
17+ public Generic () { }
18+
19+ class Inner {
20+ public Inner () { }
21+ }
22+
23+ void test () {
24+ Supplier s = Generic <Number >.Inner ::new ;
25+ }
26+ }
27+
28+ void doSomething () { }
29+
30+ static class Sub extends Test {
31+ }
32+
33+ interface SubtypeConsumer {
34+ void consume (Sub s );
35+ }
36+
37+ void test () {
38+ Function <Test > f0 = Test ::toString ;
39+ Function <Test > f1 = Test ::hashCode ;
40+ Function <Test > f2 = Test ::clone ;
41+ Function <Generic <String >> f3 = Generic <String >::toString ;
42+
43+ Supplier s0 = this ::toString ;
44+ Supplier s1 = this ::hashCode ;
45+ Supplier s2 = this ::clone ;
46+
47+ // Discards result of method call
48+ Runnable r = this ::toString ;
49+
50+ Supplier [] classInstances = {
51+ Test ::new ,
52+ Generic <String >::new ,
53+ };
54+
55+ IntFunction [] arrays = {
56+ int []::new ,
57+ Generic []::new ,
58+ };
59+
60+ // SubtypeConsumer has `Sub` as parameter type, but receiver here is `Test` (supertype)
61+ SubtypeConsumer sub = Test ::doSomething ;
62+ }
63+ }
You can’t perform that action at this time.
0 commit comments