1 /* 2 * Copyright (C) 2024 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 18 19 import com.android.tools.metalava.model.provider.Capability 20 import com.android.tools.metalava.model.testing.RequiresCapabilities 21 import com.android.tools.metalava.testing.createAndroidModuleDescription 22 import com.android.tools.metalava.testing.createCommonModuleDescription 23 import com.android.tools.metalava.testing.createProjectDescription 24 import com.android.tools.metalava.testing.getAndroidJar 25 import com.android.tools.metalava.testing.java 26 import com.android.tools.metalava.testing.kotlin 27 import com.android.tools.metalava.testing.standardProjectXmlClasspath 28 import com.android.tools.metalava.testing.xml 29 import org.junit.Test 30 31 @RequiresCapabilities(Capability.KOTLIN) 32 class ProjectDescriptionTest : DriverTest() { 33 @Test conflict declarationsnull34 fun `conflict declarations`() { 35 // Example from b/364480872 36 // Conflict declarations in Foo.java and Foo.kt are intentional. 37 // project.xml will use "androidMain" as root so that it can discard one in jvmMain. 38 check( 39 expectedIssues = 40 "jvmMain/src/some/pkg/Foo.java:3: warning: Attempted to register some.pkg.Foo twice; once from TESTROOT/androidMain/src/some/pkg/Foo.kt and this one from TESTROOT/jvmMain/src/some/pkg/Foo.java [DuplicateSourceClass]", 41 sourceFiles = 42 arrayOf( 43 kotlin( 44 "androidMain/src/some/pkg/Foo.kt", 45 """ 46 package some.pkg 47 48 class Foo { 49 companion object { 50 @JvmStatic 51 public fun foo(x: String): String { 52 return x 53 } 54 } 55 } 56 """ 57 ), 58 java( 59 "androidMain/src/test/Bar.java", 60 """ 61 package test; 62 63 import some.pkg.Foo; 64 65 public class Bar { 66 public String bar(String x) { 67 return Foo.foo(x); 68 } 69 } 70 """ 71 ), 72 java( 73 "jvmMain/src/some/pkg/Foo.java", 74 """ 75 package some.pkg; 76 77 public class Foo { 78 public static String foo(String x) { 79 return x; 80 } 81 } 82 """ 83 ), 84 ), 85 projectDescription = 86 xml( 87 "project.xml", 88 """ 89 <project> 90 <module name="app" android="true" library="false"> 91 <src file="androidMain/src/some/pkg/Foo.kt" /> 92 <src file="androidMain/src/test/Bar.java" /> 93 <classpath file="${getAndroidJar()}"/> 94 </module> 95 </project> 96 """ 97 ), 98 api = 99 """ 100 package some.pkg { 101 public final class Foo { 102 ctor public Foo(); 103 field public static final some.pkg.Foo.Companion Companion; 104 } 105 public static final class Foo.Companion { 106 method public String foo(String x); 107 } 108 } 109 package test { 110 public class Bar { 111 ctor public Bar(); 112 method public String! bar(String!); 113 } 114 } 115 """ 116 ) 117 } 118 119 @Test jvm annotations with invalid root dirnull120 fun `jvm annotations with invalid root dir`() { 121 check( 122 apiLint = "", 123 sourceFiles = 124 arrayOf( 125 kotlin( 126 "src/androidMain/some/pkg/Foo.kt", 127 """ 128 package some.pkg 129 130 class Foo { 131 @JvmName("renamed") 132 fun wrongName() = Unit 133 134 companion object { 135 @JvmStatic 136 public fun foo(x: String): String { 137 return x 138 } 139 } 140 } 141 """ 142 ), 143 ), 144 projectDescription = 145 xml( 146 "project.xml", 147 """ 148 <project> 149 <root dir="src/androidMain"/> 150 <module name="androidMain" android="true"> 151 <src file="src/androidMain/some/pkg/Foo.kt" /> 152 $standardProjectXmlClasspath 153 </module> 154 </project> 155 """ 156 ), 157 api = 158 """ 159 // Signature format: 5.0 160 package some.pkg { 161 public final class Foo { 162 ctor public Foo(); 163 method public static String foo(String x); 164 method public void renamed(); 165 field public static final some.pkg.Foo.Companion Companion; 166 } 167 public static final class Foo.Companion { 168 method public String foo(String x); 169 } 170 } 171 """ 172 ) 173 } 174 175 @Test delegate property with invalid root dirnull176 fun `delegate property with invalid root dir`() { 177 check( 178 apiLint = "", 179 sourceFiles = 180 arrayOf( 181 kotlin( 182 "src/androidMain/some/pkg/Foo.kt", 183 """ 184 package some.pkg 185 class Foo { 186 val lazyVal by lazy { 1 } 187 } 188 """ 189 ) 190 ), 191 projectDescription = 192 xml( 193 "project.xml", 194 """ 195 <project> 196 <root dir="src/androidMain"/> 197 <module name="androidMain"> 198 <src file="src/androidMain/some/pkg/Foo.kt"/> 199 $standardProjectXmlClasspath 200 </module> 201 </project> 202 """ 203 ), 204 api = 205 """ 206 // Signature format: 5.0 207 package some.pkg { 208 public final class Foo { 209 ctor public Foo(); 210 method public int getLazyVal(); 211 property public int lazyVal; 212 } 213 } 214 """ 215 ) 216 } 217 218 @Test public api in commonnull219 fun `public api in common`() { 220 val commonSrc = 221 kotlin( 222 "commonMain/src/test/pkg/Common.kt", 223 """ 224 package test.pkg 225 class Common 226 """ 227 ) 228 val androidSrc = 229 kotlin( 230 "androidMain/src/test/pkg/Android.kt", 231 """ 232 package test.pkg 233 class Android 234 """ 235 ) 236 check( 237 sourceFiles = arrayOf(androidSrc, commonSrc), 238 projectDescription = 239 createProjectDescription( 240 createAndroidModuleDescription(arrayOf(androidSrc)), 241 createCommonModuleDescription(arrayOf(commonSrc)), 242 ), 243 api = 244 """ 245 package test.pkg { 246 public final class Android { 247 ctor public Android(); 248 } 249 public final class Common { 250 ctor public Common(); 251 } 252 } 253 """ 254 ) 255 } 256 } 257