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