1 /*
2  * 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.model.testsuite.BaseModelTest
20 import com.android.tools.metalava.testing.kotlin
21 import kotlin.test.Test
22 import kotlin.test.assertEquals
23 import kotlin.test.assertFalse
24 import kotlin.test.assertNotNull
25 import kotlin.test.assertNull
26 import kotlin.test.assertSame
27 import kotlin.test.assertTrue
28 
29 class PsiParameterItemTest : BaseModelTest() {
30     @Test
primary constructor parameters have propertiesnull31     fun `primary constructor parameters have properties`() {
32         runCodebaseTest(kotlin("class Foo(val property: Int, parameter: Int)")) {
33             val constructorItem = codebase.assertClass("Foo").constructors().single()
34             val propertyParameter = constructorItem.parameters().single { it.name() == "property" }
35             val regularParameter = constructorItem.parameters().single { it.name() == "parameter" }
36 
37             assertNull(regularParameter.property)
38             assertNotNull(propertyParameter.property)
39             assertSame(propertyParameter, propertyParameter.property?.constructorParameter)
40         }
41     }
42 
43     @Test
actuals get params from expectsnull44     fun `actuals get params from expects`() {
45         val commonSource =
46             kotlin(
47                 "commonMain/src/Expect.kt",
48                 """
49                     expect suspend fun String.testFun(param: String = "")
50                     expect class Test(param: String = "") {
51                         fun something(
52                             param: String = "",
53                             otherParam: String = param + "",
54                             required: Int
55                         )
56                     }
57                 """
58             )
59         runCodebaseTest(
60             inputSet(
61                 kotlin(
62                     "jvmMain/src/Actual.kt",
63                     """
64                     actual suspend fun String.testFun(param: String) {}
65                     actual class Test actual constructor(param: String) {
66                         actual fun something(
67                             param: String = "ignored",
68                             otherParam: String,
69                             required: Int
70                         ) {}
71                     }
72                     """
73                 ),
74                 commonSource,
75             ),
76             commonSources = arrayOf(inputSet(commonSource)),
77         ) {
78             // Expect classes are ignored by UAST/Kotlin light classes, verify we test actual
79             // classes.
80             val actualFile = codebase.assertClass("ActualKt").getSourceFile()
81 
82             val functionItem = codebase.assertClass("ActualKt").methods().single()
83             with(functionItem) {
84                 val parameters = parameters()
85                 assertEquals(3, parameters.size)
86 
87                 // receiver
88                 assertFalse(parameters[0].hasDefaultValue())
89 
90                 val parameter = parameters[1]
91                 assertTrue(parameter.hasDefaultValue())
92                 assertEquals("\"\"", parameter.defaultValue())
93 
94                 // continuation
95                 assertFalse(parameters[2].hasDefaultValue())
96             }
97 
98             val classItem = codebase.assertClass("Test")
99             assertEquals(actualFile, classItem.getSourceFile())
100 
101             val constructorItem = classItem.constructors().single()
102             with(constructorItem) {
103                 val parameter = parameters().single()
104                 assertTrue(parameter.hasDefaultValue())
105                 assertEquals("\"\"", parameter.defaultValue())
106             }
107 
108             val methodItem = classItem.methods().single()
109             with(methodItem) {
110                 val parameters = parameters()
111                 assertEquals(3, parameters.size)
112 
113                 assertTrue(parameters[0].hasDefaultValue())
114                 assertEquals("\"\"", parameters[0].defaultValue())
115 
116                 assertTrue(parameters[1].hasDefaultValue())
117                 assertEquals("param + \"\"", parameters[1].defaultValue())
118 
119                 assertFalse(parameters[2].hasDefaultValue())
120             }
121         }
122     }
123 }
124