• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 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 com.android.tools.metalava.model.psi
18 
19 import com.android.tools.metalava.kotlin
20 import com.android.tools.metalava.model.VisibilityLevel
21 import kotlin.test.Test
22 import kotlin.test.assertEquals
23 import kotlin.test.assertFalse
24 import kotlin.test.assertTrue
25 
26 class PsiModifierItemTest {
27     @Test
28     fun `Kotlin implicit internal visibility inheritance`() {
29         testCodebase(
30             kotlin(
31                 """
32                     open class Base {
33                         internal open fun method(): Int = 1
34                         internal open val property: Int = 2
35                     }
36 
37                     class Inherited : Base() {
38                         override fun method(): Int = 3
39                         override val property = 4
40                     }
41                 """
42             )
43         ) { codebase ->
44             val inherited = codebase.assertClass("Inherited")
45             val method = inherited.methods().first { it.name().startsWith("method") }
46             val property = inherited.properties().single()
47 
48             assertEquals(VisibilityLevel.INTERNAL, method.modifiers.getVisibilityLevel())
49             assertEquals(VisibilityLevel.INTERNAL, property.modifiers.getVisibilityLevel())
50         }
51     }
52 
53     @Test
54     fun `Kotlin class visibility modifiers`() {
55         testCodebase(
56             kotlin(
57                 """
58                     internal class Internal
59                     public class Public
60                     class DefaultPublic
61                     abstract class Outer {
62                         private class Private
63                         protected class Protected
64                     }
65                 """
66             )
67         ) { codebase ->
68             assertTrue(codebase.assertClass("Internal").isInternal)
69             assertTrue(codebase.assertClass("Public").isPublic)
70             assertTrue(codebase.assertClass("DefaultPublic").isPublic)
71             assertTrue(codebase.assertClass("Outer.Private").isPrivate)
72             assertTrue(codebase.assertClass("Outer.Protected").isProtected)
73         }
74     }
75 
76     @Test
77     fun `Kotlin class abstract and final modifiers`() {
78         testCodebase(
79             kotlin(
80                 """
81                     abstract class Abstract
82                     sealed class Sealed
83                     open class Open
84                     final class Final
85                     class FinalDefault
86                     interface Interface
87                     annotation class Annotation
88                 """
89             )
90         ) { codebase ->
91             codebase.assertClass("Abstract").modifiers.let {
92                 assertTrue(it.isAbstract())
93                 assertFalse(it.isSealed())
94                 assertFalse(it.isFinal())
95             }
96 
97             codebase.assertClass("Sealed").modifiers.let {
98                 assertTrue(it.isAbstract())
99                 assertTrue(it.isSealed())
100                 assertFalse(it.isFinal())
101             }
102 
103             codebase.assertClass("Open").modifiers.let {
104                 assertFalse(it.isAbstract())
105                 assertFalse(it.isFinal())
106             }
107 
108             codebase.assertClass("Final").modifiers.let {
109                 assertFalse(it.isAbstract())
110                 assertTrue(it.isFinal())
111             }
112 
113             codebase.assertClass("FinalDefault").modifiers.let {
114                 assertFalse(it.isAbstract())
115                 assertTrue(it.isFinal())
116             }
117 
118             codebase.assertClass("Interface").modifiers.let {
119                 assertTrue(it.isAbstract())
120                 assertFalse(it.isFinal())
121             }
122 
123             codebase.assertClass("Annotation").modifiers.let {
124                 assertTrue(it.isAbstract())
125                 assertFalse(it.isFinal())
126             }
127         }
128     }
129 
130     @Test
131     fun `Kotlin class type modifiers`() {
132         testCodebase(
133             kotlin(
134                 """
135                     inline class Inline(val value: Int)
136                     value class Value(val value: Int)
137                     data class Data(val data: Int) {
138                         companion object {
139                             const val DATA = 0
140                         }
141                     }
142                     fun interface FunInterface {
143                         fun foo()
144                     }
145                 """
146             )
147         ) { codebase ->
148             assertTrue(codebase.assertClass("Inline").modifiers.isInline())
149             assertTrue(codebase.assertClass("Value").modifiers.isValue())
150             assertTrue(codebase.assertClass("Data").modifiers.isData())
151             assertTrue(codebase.assertClass("Data.Companion").modifiers.isCompanion())
152             assertTrue(codebase.assertClass("FunInterface").modifiers.isFunctional())
153         }
154     }
155 
156     @Test
157     fun `Kotlin class static modifiers`() {
158         testCodebase(
159             kotlin(
160                 """
161                     class TopLevel {
162                         inner class Inner
163                         class Nested
164                         interface Interface
165                         annotation class Annotation
166                         object Object
167                     }
168                     object Object
169                 """
170             )
171         ) { codebase ->
172 
173             assertFalse(codebase.assertClass("TopLevel").modifiers.isStatic())
174             assertFalse(codebase.assertClass("TopLevel.Inner").modifiers.isStatic())
175             assertFalse(codebase.assertClass("Object").modifiers.isStatic())
176 
177             assertTrue(codebase.assertClass("TopLevel.Nested").modifiers.isStatic())
178             assertTrue(codebase.assertClass("TopLevel.Interface").modifiers.isStatic())
179             assertTrue(codebase.assertClass("TopLevel.Annotation").modifiers.isStatic())
180             assertTrue(codebase.assertClass("TopLevel.Object").modifiers.isStatic())
181         }
182     }
183 
184     fun `Kotlin vararg parameters`() {
185         testCodebase(
186             kotlin(
187                 "Foo.kt",
188                 """
189                     fun varArg(vararg parameter: Int) { TODO() }
190                     fun nonVarArg(parameter: Int) { TODO() }
191                 """
192             )
193         ) { codebase ->
194             val facade = codebase.assertClass("FooKt")
195             val varArg = facade.methods().single { it.name() == "varArg" }.parameters().single()
196             val nonVarArg =
197                 facade.methods().single { it.name() == "nonVarArg" }.parameters().single()
198 
199             assertTrue(varArg.modifiers.isVarArg())
200             assertFalse(nonVarArg.modifiers.isVarArg())
201         }
202     }
203 }
204