1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package sample.optin;
18 
19 import androidx.annotation.OptIn;
20 
21 @SuppressWarnings({"unused", "WeakerAccess"})
22 class UseKtExperimentalFromJava {
23 
24     /**
25      * Unsafe call into an experimental class.
26      */
unsafeExperimentalClassField()27     int unsafeExperimentalClassField() {
28         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
29         return experimentalObject.method();
30     }
31 
32     /**
33      * Safe call due to propagation of experimental annotation.
34      */
35     @ExperimentalKotlinAnnotation
safePropagateMarker()36     int safePropagateMarker() {
37         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
38         return experimentalObject.method();
39     }
40 
41     /**
42      * Safe call due to opting in to experimental annotation.
43      */
44     @OptIn(markerClass = ExperimentalKotlinAnnotation.class)
safeOptInMarker()45     int safeOptInMarker() {
46         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
47         return experimentalObject.method();
48     }
49 
50     /**
51      * Unsafe call into multiple experimental classes.
52      */
53     @ExperimentalKotlinAnnotation
unsafeMultipleExperimentalClasses()54     int unsafeMultipleExperimentalClasses() {
55         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
56         return experimentalObject.method() + AnnotatedKotlinClass2.fieldStatic;
57     }
58 
59     /**
60      * Safe call due to propagation of both annotations.
61      */
62     @ExperimentalKotlinAnnotation
63     @ExperimentalKotlinAnnotation2
safePropagateMultipleMarkers()64     int safePropagateMultipleMarkers() {
65         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
66         return experimentalObject.method() + AnnotatedKotlinClass2.fieldStatic;
67     }
68 
69     /**
70      * Safe call due to opt-in of one annotation and propagation of another.
71      */
72     @OptIn(markerClass = ExperimentalKotlinAnnotation.class)
73     @ExperimentalKotlinAnnotation2
safePropagateAndOptInMarkers()74     int safePropagateAndOptInMarkers() {
75         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
76         return experimentalObject.method() + AnnotatedKotlinClass2.fieldStatic;
77     }
78 
79     /**
80      * Safe call due to opt-in of both annotations.
81      */
82     @OptIn(markerClass = {
83             ExperimentalKotlinAnnotation.class,
84             ExperimentalKotlinAnnotation2.class
85     })
safeOptInMultipleMarkers()86     int safeOptInMultipleMarkers() {
87         AnnotatedKotlinClass experimentalObject = new AnnotatedKotlinClass();
88         return experimentalObject.method() + AnnotatedKotlinClass2.fieldStatic;
89     }
90 
91     /**
92      * Unsafe calls into static methods.
93      *
94      * Regression test for issue reported in b/140637106, which passes here but fails in Studio.
95      */
regressionTestStaticUsage()96     void regressionTestStaticUsage() {
97         AnnotatedKotlinMembers.methodStatic();
98         AnnotatedKotlinMembers.Companion.methodStatic();
99     }
100 
101     /**
102      * Unsafe calls into methods without intermediate variable.
103      *
104      * Regression test for issue reported in b/140637106, which passes here but fails in Studio.
105      */
regressionTestInlineUsage()106     void regressionTestInlineUsage() {
107         new AnnotatedKotlinMembers().method();
108         new AnnotatedKotlinMembers().methodWithJavaMarker();
109     }
110 
111     /**
112      * Unsafe references to experimental properties.
113      */
unsafePropertyUsage()114     void unsafePropertyUsage() {
115         new AnnotatedKotlinMembers().setField(-1);
116         int value = new AnnotatedKotlinMembers().getField();
117         new AnnotatedKotlinMembers().setFieldWithSetMarker(-1);
118         int value2 = new AnnotatedKotlinMembers().getFieldWithSetMarker(); // safe
119     }
120 
121     /**
122      * Safe usage due to opting in to experimental annotation.
123      */
124     @OptIn(markerClass = ExperimentalKotlinAnnotation.class)
125     static class ExtendsAnnotatedKotlinClass extends AnnotatedKotlinClass {}
126 
127     /**
128      * Safe usage due to opting in to experimental annotation.
129      */
130     @kotlin.OptIn(markerClass = ExperimentalKotlinAnnotation.class)
131     static class ExtendsAnnotatedKotlinClass2 extends AnnotatedKotlinClass {}
132 }
133