File tree Expand file tree Collapse file tree 4 files changed +109
-0
lines changed
test/library-tests/MemberRefExpr Expand file tree Collapse file tree 4 files changed +109
-0
lines changed Original file line number Diff line number Diff line change @@ -1227,6 +1227,28 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
1227
1227
*/
1228
1228
override Method asMethod ( ) { result = this .getAnonymousClass ( ) .getAMethod ( ) }
1229
1229
1230
+ /**
1231
+ * Gets the receiver type whose member this expression refers to. The result might not be
1232
+ * the type which actually declares the member. For example, for the member reference `ArrayList::toString`,
1233
+ * this predicate has the result `java.util.ArrayList`, the type explicitly referred to, while
1234
+ * `getReferencedCallable` will have `java.util.AbstractCollection.toString` as result, which `ArrayList` inherits.
1235
+ */
1236
+ RefType getReceiverType ( ) {
1237
+ exists ( Stmt stmt , Expr resultExpr |
1238
+ stmt = asMethod ( ) .getBody ( ) .( SingletonBlock ) .getStmt ( ) and
1239
+ (
1240
+ resultExpr = stmt .( ReturnStmt ) .getResult ( )
1241
+ or
1242
+ // Note: Currently never an ExprStmt, but might change once https://github.com/github/codeql/issues/3605 is fixed
1243
+ resultExpr = stmt .( ExprStmt ) .getExpr ( )
1244
+ )
1245
+ |
1246
+ result = resultExpr .( MethodAccess ) .getReceiverType ( ) or
1247
+ result = resultExpr .( ClassInstanceExpr ) .getConstructedType ( ) or
1248
+ result = resultExpr .( ArrayCreationExpr ) .getType ( )
1249
+ )
1250
+ }
1251
+
1230
1252
/**
1231
1253
* Gets the method or constructor referenced by this member reference expression.
1232
1254
*/
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