File: ReceiversMethodref.java

package info (click to toggle)
checker-framework-java 3.2.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 23,104 kB
  • sloc: java: 145,916; xml: 839; sh: 518; makefile: 404; perl: 26
file content (86 lines) | stat: -rw-r--r-- 2,135 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import org.checkerframework.checker.nullness.qual.*;

// Nullable receivers don't make a lot of sense
// But this class tests the sub supertype recevier relationships.
// It could just use tainted.

interface Unbound1 {
    void apply(@NonNull MyClass my);
}

interface Unbound2 {
    void apply(@Nullable MyClass my);
}

interface Supplier1<R extends @Nullable Object> {
    R supply();
}

interface Bound {
    void apply();
}

class MyClass {
    void take(@NonNull MyClass this) {}

    void context1(@Nullable MyClass this, @NonNull MyClass my1, @Nullable MyClass my2) {

        Unbound1 u1 = MyClass::take;
        // :: error: (methodref.receiver.invalid)
        Unbound2 u2 = MyClass::take;

        Bound b1 = my1::take;
        // :: error: (methodref.receiver.bound.invalid)
        Bound b2 = my2::take;

        // :: error: (methodref.receiver.bound.invalid)
        Bound b11 = this::take;
    }

    void context2(@NonNull MyClass this) {
        Bound b21 = this::take;
    }

    class MySubClass extends MyClass {

        void context1(@Nullable MySubClass this) {
            // :: error: (methodref.receiver.bound.invalid)
            Bound b = super::take;
        }

        void context2(@NonNull MySubClass this) {
            Bound b = super::take;
        }

        class Nested {
            void context1(@Nullable Nested this) {
                // :: error: (methodref.receiver.bound.invalid)
                Bound b = MySubClass.super::take;
            }

            void context2(@NonNull Nested this) {
                Bound b = MySubClass.super::take;
            }
        }
    }
}

class Outer {
    class Inner1 {
        Inner1(@Nullable Outer Outer.this) {}
    }

    class Inner2 {
        Inner2(@NonNull Outer Outer.this) {}
    }

    void context(@Nullable Outer this) {
        // This one is unbound and needs an Outer as a param
        Supplier1<Inner1> f1 = Inner1::new;
        // :: error: (methodref.receiver.bound.invalid)
        Supplier1<Inner2> f2 = Inner2::new;

        // Supplier1</*3*/Inner> f = /*4*/Inner::new;
        // 4 <: 3? Constructor annotations?
    }
}