• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.FilterAction.EXCLUDE
21 import com.android.tools.metalava.model.testing.FilterByProvider
22 import com.android.tools.metalava.model.testing.RequiresCapabilities
23 import com.android.tools.metalava.model.text.FileFormat
24 import com.android.tools.metalava.testing.createAndroidModuleDescription
25 import com.android.tools.metalava.testing.createCommonModuleDescription
26 import com.android.tools.metalava.testing.createModuleDescription
27 import com.android.tools.metalava.testing.createProjectDescription
28 import com.android.tools.metalava.testing.kotlin
29 import org.junit.Test
30 
31 /** Base class to collect test inputs whose behaviors (API/lint) vary depending on UAST versions. */
32 @RequiresCapabilities(Capability.KOTLIN)
33 abstract class UastTestBase : DriverTest() {
34 
35     @Test
Test RequiresOptIn and OptInnull36     fun `Test RequiresOptIn and OptIn`() {
37         // See http://b/248341155 for more details
38         val klass = if (isK2) "Class" else "kotlin.reflect.KClass"
39         check(
40             sourceFiles =
41                 arrayOf(
42                     kotlin(
43                         """
44                     package test.pkg
45 
46                     @RequiresOptIn
47                     @Retention(AnnotationRetention.BINARY)
48                     @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
49                     annotation class ExperimentalBar
50 
51                     @ExperimentalBar
52                     class FancyBar
53 
54                     @OptIn(FancyBar::class) // @OptIn should not be tracked as it is not API
55                     class SimpleClass {
56                         fun methodUsingFancyBar() {
57                             val fancyBar = FancyBar()
58                         }
59                     }
60 
61                     @androidx.annotation.experimental.UseExperimental(FancyBar::class) // @UseExperimental should not be tracked as it is not API
62                     class AnotherSimpleClass {
63                         fun methodUsingFancyBar() {
64                             val fancyBar = FancyBar()
65                         }
66                     }
67                 """
68                     ),
69                     kotlin(
70                         """
71                     package androidx.annotation.experimental
72 
73                     import kotlin.annotation.Retention
74                     import kotlin.annotation.Target
75                     import kotlin.reflect.KClass
76 
77                     @Retention(AnnotationRetention.BINARY)
78                     @Target(
79                         AnnotationTarget.CLASS,
80                         AnnotationTarget.PROPERTY,
81                         AnnotationTarget.LOCAL_VARIABLE,
82                         AnnotationTarget.VALUE_PARAMETER,
83                         AnnotationTarget.CONSTRUCTOR,
84                         AnnotationTarget.FUNCTION,
85                         AnnotationTarget.PROPERTY_GETTER,
86                         AnnotationTarget.PROPERTY_SETTER,
87                         AnnotationTarget.FILE,
88                         AnnotationTarget.TYPEALIAS
89                     )
90                     annotation class UseExperimental(
91                         /**
92                          * Defines the experimental API(s) whose usage this annotation allows.
93                          */
94                         vararg val markerClass: KClass<out Annotation>
95                     )
96                 """
97                     )
98                 ),
99             format = FileFormat.V4,
100             api =
101                 """
102                 // Signature format: 4.0
103                 package androidx.annotation.experimental {
104                   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.LOCAL_VARIABLE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface UseExperimental {
105                     method public abstract $klass<? extends java.lang.annotation.Annotation>[] markerClass();
106                     property public abstract $klass<? extends java.lang.annotation.Annotation>[] markerClass;
107                   }
108                 }
109                 package test.pkg {
110                   public final class AnotherSimpleClass {
111                     ctor public AnotherSimpleClass();
112                     method public void methodUsingFancyBar();
113                   }
114                   @kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalBar {
115                   }
116                   @test.pkg.ExperimentalBar public final class FancyBar {
117                     ctor public FancyBar();
118                   }
119                   public final class SimpleClass {
120                     ctor public SimpleClass();
121                     method public void methodUsingFancyBar();
122                   }
123                 }
124             """
125         )
126     }
127 
128     @Test
renamed via @JvmNamenull129     fun `renamed via @JvmName`() {
130         val api =
131             if (isK2) {
132                 // NB: getInterpolated -> isInterpolated
133                 """
134                     // Signature format: 4.0
135                     package test.pkg {
136                       public final class ColorRamp {
137                         ctor public ColorRamp(int[] colors, boolean interpolated);
138                         method public int[] getColors();
139                         method public int[] getOtherColors();
140                         method public boolean isInitiallyEnabled();
141                         method public boolean isInterpolated();
142                         method public void updateOtherColors(int[]);
143                         property public int[] colors;
144                         property public boolean initiallyEnabled;
145                         property public boolean interpolated;
146                         property public int[] otherColors;
147                       }
148                     }
149                 """
150             } else {
151                 """
152                     // Signature format: 4.0
153                     package test.pkg {
154                       public final class ColorRamp {
155                         ctor public ColorRamp(int[] colors, boolean interpolated);
156                         method public int[] getColors();
157                         method public boolean getInterpolated();
158                         method public int[] getOtherColors();
159                         method public boolean isInitiallyEnabled();
160                         method public void updateOtherColors(int[]);
161                         property public int[] colors;
162                         property public boolean initiallyEnabled;
163                         property public boolean interpolated;
164                         property public int[] otherColors;
165                       }
166                     }
167                 """
168             }
169         // Regression test from http://b/257444932: @get:JvmName on constructor property
170         check(
171             sourceFiles =
172                 arrayOf(
173                     kotlin(
174                         """
175                         package test.pkg
176 
177                         class ColorRamp(
178                             val colors: IntArray,
179                             @get:JvmName("isInterpolated")
180                             val interpolated: Boolean,
181                         ) {
182                             @get:JvmName("isInitiallyEnabled")
183                             val initiallyEnabled: Boolean = false
184 
185                             @set:JvmName("updateOtherColors")
186                             var otherColors: IntArray = arrayOf()
187                         }
188                     """
189                     )
190                 ),
191             format = FileFormat.V4,
192             api = api,
193         )
194     }
195 
196     @Test
Annotation on parameters of data class synthetic copynull197     fun `Annotation on parameters of data class synthetic copy`() {
198         // https://youtrack.jetbrains.com/issue/KT-57003
199         check(
200             sourceFiles =
201                 arrayOf(
202                     kotlin(
203                         """
204                         package test.pkg
205                         annotation class MyAnnotation
206 
207                         data class Foo(@MyAnnotation val p1: Int, val p2: String)
208                     """
209                     )
210                 ),
211             api =
212                 """
213                 package test.pkg {
214                   public final class Foo {
215                     ctor public Foo(@test.pkg.MyAnnotation int p1, String p2);
216                     method public int component1();
217                     method public String component2();
218                     method public test.pkg.Foo copy(@test.pkg.MyAnnotation int p1, String p2);
219                     method public int getP1();
220                     method public String getP2();
221                     property @test.pkg.MyAnnotation public int p1;
222                     property public String p2;
223                   }
224                   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface MyAnnotation {
225                   }
226                 }
227             """
228         )
229     }
230 
231     @Test
declarations with value class in its signaturenull232     fun `declarations with value class in its signature`() {
233         // https://youtrack.jetbrains.com/issue/KT-57546
234         // https://youtrack.jetbrains.com/issue/KT-57577
235         // https://youtrack.jetbrains.com/issue/KT-72078
236         check(
237             sourceFiles =
238                 arrayOf(
239                     kotlin(
240                         """
241                         package test.pkg
242                         @kotlin.jvm.JvmInline
243                         value class AnchorType internal constructor(internal val ratio: Float) {
244                             companion object {
245                                 val Start = AnchorType(0f)
246                                 val Center = AnchorType(0.5f)
247                                 val End = AnchorType(1f)
248                             }
249                         }
250                         class User(
251                           val p : AnchorType,
252                           var q : AnchorType,
253                         ) {
254                           fun foo() = p
255                           fun bar(): () -> AnchorType = { foo() }
256                         }
257 
258                         class Alignment(val horizontal: Horizontal, val vertical: Vertical) {
259                           @kotlin.jvm.JvmInline
260                           value class Horizontal private constructor(private val value: Int) {
261                             companion object {
262                               val Start: Horizontal = Horizontal(0)
263                               val CenterHorizontally: Horizontal = Horizontal(1)
264                               val End: Horizontal = Horizontal(2)
265                             }
266                           }
267 
268                           @kotlin.jvm.JvmInline
269                           value class Vertical private constructor(private val value: Int) {
270                             companion object {
271                               val Top: Vertical = Vertical(0)
272                               val CenterVertically: Vertical = Vertical(1)
273                               val Bottom: Vertical = Vertical(2)
274                             }
275                           }
276 
277                           companion object {
278                             val TopStart: Alignment = Alignment(Horizontal.Start, Vertical.Top)
279                             val Top: Vertical = Vertical.Top
280                             val Start: Horizontal = Horizontal.Start
281                           }
282                         }
283                     """
284                     )
285                 ),
286             api =
287                 """
288                 package test.pkg {
289                   public final class Alignment {
290                     ctor public Alignment(int horizontal, int vertical);
291                     method public int getHorizontal();
292                     method public int getVertical();
293                     property public int horizontal;
294                     property public int vertical;
295                     field public static final test.pkg.Alignment.Companion Companion;
296                   }
297                   public static final class Alignment.Companion {
298                     method public int getStart();
299                     method public int getTop();
300                     method public test.pkg.Alignment getTopStart();
301                     property public int Start;
302                     property public int Top;
303                     property public test.pkg.Alignment TopStart;
304                   }
305                   @kotlin.jvm.JvmInline public static final value class Alignment.Horizontal {
306                     field public static final test.pkg.Alignment.Horizontal.Companion Companion;
307                   }
308                   public static final class Alignment.Horizontal.Companion {
309                     method public int getCenterHorizontally();
310                     method public int getEnd();
311                     method public int getStart();
312                     property public int CenterHorizontally;
313                     property public int End;
314                     property public int Start;
315                   }
316                   @kotlin.jvm.JvmInline public static final value class Alignment.Vertical {
317                     field public static final test.pkg.Alignment.Vertical.Companion Companion;
318                   }
319                   public static final class Alignment.Vertical.Companion {
320                     method public int getBottom();
321                     method public int getCenterVertically();
322                     method public int getTop();
323                     property public int Bottom;
324                     property public int CenterVertically;
325                     property public int Top;
326                   }
327                   @kotlin.jvm.JvmInline public final value class AnchorType {
328                     field public static final test.pkg.AnchorType.Companion Companion;
329                   }
330                   public static final class AnchorType.Companion {
331                     method public float getCenter();
332                     method public float getEnd();
333                     method public float getStart();
334                     property public float Center;
335                     property public float End;
336                     property public float Start;
337                   }
338                   public final class User {
339                     ctor public User(float p, float q);
340                     method public kotlin.jvm.functions.Function0<test.pkg.AnchorType> bar();
341                     method public float foo();
342                     method public float getP();
343                     method public float getQ();
344                     method public void setQ(float);
345                     property public float p;
346                     property public float q;
347                   }
348                 }
349         """
350         )
351     }
352 
353     @FilterByProvider("psi", "k2", action = EXCLUDE)
354     @Test
internal setter with delegationnull355     fun `internal setter with delegation`() {
356         // https://youtrack.jetbrains.com/issue/KT-70458
357         check(
358             sourceFiles =
359                 arrayOf(
360                     kotlin(
361                         """
362                         package test.pkg
363                         class Test {
364                           var prop = "zzz"
365                             internal set
366                           var lazyProp by lazy { setOf("zzz") }
367                             internal set
368                         }
369                         """
370                     )
371                 ),
372             api =
373                 """
374                 package test.pkg {
375                   public final class Test {
376                     ctor public Test();
377                     method public java.util.Set<java.lang.String> getLazyProp();
378                     method public String getProp();
379                     property public java.util.Set<java.lang.String> lazyProp;
380                     property public String prop;
381                   }
382                 }
383                 """
384         )
385     }
386 
387     @Test
non-last vararg typenull388     fun `non-last vararg type`() {
389         // https://youtrack.jetbrains.com/issue/KT-57547
390         check(
391             sourceFiles =
392                 arrayOf(
393                     kotlin(
394                         """
395                         package test.pkg
396                         fun foo(vararg vs: String, b: Boolean = true) {
397                         }
398                     """
399                     )
400                 ),
401             api =
402                 """
403                 package test.pkg {
404                   public final class TestKt {
405                     method public static void foo(String[] vs, optional boolean b);
406                   }
407                 }
408             """
409         )
410     }
411 
412     @Test
implements Comparatornull413     fun `implements Comparator`() {
414         // https://youtrack.jetbrains.com/issue/KT-57548
415         check(
416             sourceFiles =
417                 arrayOf(
418                     kotlin(
419                         """
420                         package test.pkg
421                         class Foo(val x : Int)
422                         class FooComparator : Comparator<Foo> {
423                           override fun compare(firstFoo: Foo, secondFoo: Foo): Int =
424                             firstFoo.x - secondFoo.x
425                         }
426                     """
427                     )
428                 ),
429             api =
430                 """
431                 package test.pkg {
432                   public final class Foo {
433                     ctor public Foo(int x);
434                     method public int getX();
435                     property public int x;
436                   }
437                   public final class FooComparator implements java.util.Comparator<test.pkg.Foo> {
438                     ctor public FooComparator();
439                     method public int compare(test.pkg.Foo firstFoo, test.pkg.Foo secondFoo);
440                   }
441                 }
442             """
443         )
444     }
445 
446     @Test
constant in file-level annotationnull447     fun `constant in file-level annotation`() {
448         // https://youtrack.jetbrains.com/issue/KT-57550
449         check(
450             sourceFiles =
451                 arrayOf(
452                     kotlin(
453                         """
454                         @file:RequiresApi(31)
455                         package test.pkg
456                         import androidx.annotation.RequiresApi
457 
458                         @RequiresApi(31)
459                         fun foo(p: Int) {}
460                     """
461                     ),
462                     requiresApiSource,
463                 ),
464             api =
465                 """
466                 package test.pkg {
467                   @RequiresApi(31) public final class TestKt {
468                     method @RequiresApi(31) public static void foo(int p);
469                   }
470                 }
471             """
472         )
473     }
474 
475     @Test
final modifier in enum membersnull476     fun `final modifier in enum members`() {
477         // https://youtrack.jetbrains.com/issue/KT-57567
478         check(
479             sourceFiles =
480                 arrayOf(
481                     kotlin(
482                         """
483                         package test.pkg
484                         enum class Event {
485                           ON_CREATE, ON_START, ON_STOP, ON_DESTROY;
486                           companion object {
487                             @JvmStatic
488                             fun upTo(state: State): Event? {
489                               return when(state) {
490                                 State.ENQUEUED -> ON_CREATE
491                                 State.RUNNING -> ON_START
492                                 State.BLOCKED -> ON_STOP
493                                 else -> null
494                               }
495                             }
496                           }
497                         }
498                         enum class State {
499                           ENQUEUED, RUNNING, SUCCEEDED, FAILED, BLOCKED, CANCELLED;
500                           val isFinished: Boolean
501                             get() = this == SUCCEEDED || this == FAILED || this == CANCELLED
502                           fun isAtLeast(state: State): Boolean {
503                             return compareTo(state) >= 0
504                           }
505                         }
506                     """
507                     )
508                 ),
509             api =
510                 """
511                 package test.pkg {
512                   public enum Event {
513                     method public static test.pkg.Event? upTo(test.pkg.State state);
514                     enum_constant public static final test.pkg.Event ON_CREATE;
515                     enum_constant public static final test.pkg.Event ON_DESTROY;
516                     enum_constant public static final test.pkg.Event ON_START;
517                     enum_constant public static final test.pkg.Event ON_STOP;
518                     field public static final test.pkg.Event.Companion Companion;
519                   }
520                   public static final class Event.Companion {
521                     method public test.pkg.Event? upTo(test.pkg.State state);
522                   }
523                   public enum State {
524                     method public boolean isAtLeast(test.pkg.State state);
525                     method public boolean isFinished();
526                     property public boolean isFinished;
527                     enum_constant public static final test.pkg.State BLOCKED;
528                     enum_constant public static final test.pkg.State CANCELLED;
529                     enum_constant public static final test.pkg.State ENQUEUED;
530                     enum_constant public static final test.pkg.State FAILED;
531                     enum_constant public static final test.pkg.State RUNNING;
532                     enum_constant public static final test.pkg.State SUCCEEDED;
533                   }
534                 }
535             """
536         )
537     }
538 
539     @Test
lateinit var as mutable bare fieldnull540     fun `lateinit var as mutable bare field`() {
541         // https://youtrack.jetbrains.com/issue/KT-57569
542         check(
543             sourceFiles =
544                 arrayOf(
545                     kotlin(
546                         """
547                         package test.pkg
548                         class Bar
549                         class Foo {
550                           lateinit var bars: List<Bar>
551                             private set
552                         }
553                     """
554                     )
555                 ),
556             api =
557                 """
558                 package test.pkg {
559                   public final class Bar {
560                     ctor public Bar();
561                   }
562                   public final class Foo {
563                     ctor public Foo();
564                     method public java.util.List<test.pkg.Bar> getBars();
565                     property public java.util.List<test.pkg.Bar> bars;
566                   }
567                 }
568             """
569         )
570     }
571 
572     @Test
Upper bound wildcards -- enum membersnull573     fun `Upper bound wildcards -- enum members`() {
574         // https://youtrack.jetbrains.com/issue/KT-57578
575         val upperBound = "? extends "
576         check(
577             sourceFiles =
578                 arrayOf(
579                     kotlin(
580                         """
581                         package test.pkg
582                         enum class PowerCategoryDisplayLevel {
583                           BREAKDOWN, TOTAL
584                         }
585 
586                         enum class PowerCategory {
587                           CPU, MEMORY
588                         }
589 
590                         class PowerMetric {
591                           companion object {
592                             @JvmStatic
593                             fun Battery(): Type.Battery {
594                               return Type.Battery()
595                             }
596 
597                             @JvmStatic
598                             fun Energy(
599                               categories: Map<PowerCategory, PowerCategoryDisplayLevel> = emptyMap()
600                             ): Type.Energy {
601                               return Type.Energy(categories)
602                             }
603 
604                             @JvmStatic
605                             fun Power(
606                               categories: Map<PowerCategory, PowerCategoryDisplayLevel> = emptyMap()
607                             ): Type.Power {
608                               return Type.Power(categories)
609                             }
610                           }
611                           sealed class Type(var categories: Map<PowerCategory, PowerCategoryDisplayLevel> = emptyMap()) {
612                             class Power(
613                               powerCategories: Map<PowerCategory, PowerCategoryDisplayLevel> = emptyMap()
614                             ) : Type(powerCategories)
615 
616                             class Energy(
617                               energyCategories: Map<PowerCategory, PowerCategoryDisplayLevel> = emptyMap()
618                             ) : Type(energyCategories)
619 
620                             class Battery : Type()
621                           }
622                         }
623                     """
624                     )
625                 ),
626             api =
627                 """
628                 package test.pkg {
629                   public enum PowerCategory {
630                     enum_constant public static final test.pkg.PowerCategory CPU;
631                     enum_constant public static final test.pkg.PowerCategory MEMORY;
632                   }
633                   public enum PowerCategoryDisplayLevel {
634                     enum_constant public static final test.pkg.PowerCategoryDisplayLevel BREAKDOWN;
635                     enum_constant public static final test.pkg.PowerCategoryDisplayLevel TOTAL;
636                   }
637                   public final class PowerMetric {
638                     ctor public PowerMetric();
639                     method public static test.pkg.PowerMetric.Type.Battery Battery();
640                     method public static test.pkg.PowerMetric.Type.Energy Energy(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> categories);
641                     method public static test.pkg.PowerMetric.Type.Power Power(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> categories);
642                     field public static final test.pkg.PowerMetric.Companion Companion;
643                   }
644                   public static final class PowerMetric.Companion {
645                     method public test.pkg.PowerMetric.Type.Battery Battery();
646                     method public test.pkg.PowerMetric.Type.Energy Energy(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> categories);
647                     method public test.pkg.PowerMetric.Type.Power Power(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> categories);
648                   }
649                   public abstract static sealed class PowerMetric.Type {
650                     method public final java.util.Map<test.pkg.PowerCategory,test.pkg.PowerCategoryDisplayLevel> getCategories();
651                     method public final void setCategories(java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel>);
652                     property public final java.util.Map<test.pkg.PowerCategory,test.pkg.PowerCategoryDisplayLevel> categories;
653                   }
654                   public static final class PowerMetric.Type.Battery extends test.pkg.PowerMetric.Type {
655                     ctor public PowerMetric.Type.Battery();
656                   }
657                   public static final class PowerMetric.Type.Energy extends test.pkg.PowerMetric.Type {
658                     ctor public PowerMetric.Type.Energy();
659                     ctor public PowerMetric.Type.Energy(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> energyCategories);
660                   }
661                   public static final class PowerMetric.Type.Power extends test.pkg.PowerMetric.Type {
662                     ctor public PowerMetric.Type.Power();
663                     ctor public PowerMetric.Type.Power(optional java.util.Map<test.pkg.PowerCategory,${upperBound}test.pkg.PowerCategoryDisplayLevel> powerCategories);
664                   }
665                 }
666             """
667         )
668     }
669 
670     @Test
Upper bound wildcards -- type aliasnull671     fun `Upper bound wildcards -- type alias`() {
672         // https://youtrack.jetbrains.com/issue/KT-61460
673         check(
674             sourceFiles =
675                 arrayOf(
676                     kotlin(
677                         """
678                         package test.pkg
679 
680                         class PerfettoSdkHandshake(
681                           private val targetPackage: String,
682                           private val parseJsonMap: (jsonString: String) -> Map<String, String>,
683                           private val executeShellCommand: ShellCommandExecutor,
684                         )
685 
686                         internal typealias ShellCommandExecutor = (command: String) -> String
687                         """
688                     )
689                 ),
690             api =
691                 """
692                 package test.pkg {
693                   public final class PerfettoSdkHandshake {
694                     ctor public PerfettoSdkHandshake(String targetPackage, kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.util.Map<java.lang.String,java.lang.String>> parseJsonMap, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.String> executeShellCommand);
695                   }
696                 }
697                 """
698         )
699     }
700 
701     @Test
Upper bound wildcards -- extension function typenull702     fun `Upper bound wildcards -- extension function type`() {
703         // https://youtrack.jetbrains.com/issue/KT-61734
704         check(
705             sourceFiles =
706                 arrayOf(
707                     kotlin(
708                         """
709                         package test.pkg
710 
711                         interface NavGraphBuilder
712 
713                         interface AnimatedContentTransitionScope<S>
714 
715                         interface NavBackStackEntry
716 
717                         interface EnterTransition
718 
719                         fun NavGraphBuilder.compose(
720                           enterTransition: (@JvmSuppressWildcards
721                               AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? = null,
722                         ) = TODO()
723                         """
724                     )
725                 ),
726             api =
727                 """
728                 package test.pkg {
729                   public interface AnimatedContentTransitionScope<S> {
730                   }
731                   public interface EnterTransition {
732                   }
733                   public interface NavBackStackEntry {
734                   }
735                   public interface NavGraphBuilder {
736                   }
737                   public final class NavGraphBuilderKt {
738                     method public static Void compose(test.pkg.NavGraphBuilder, optional kotlin.jvm.functions.Function1<test.pkg.AnimatedContentTransitionScope<test.pkg.NavBackStackEntry>,test.pkg.EnterTransition?>? enterTransition);
739                   }
740                 }
741                 """
742         )
743     }
744 
745     @Test
Upper bound wildcards -- extension function type -- deprecatednull746     fun `Upper bound wildcards -- extension function type -- deprecated`() {
747         // https://youtrack.jetbrains.com/issue/KT-61734
748         val wildcard1 = if (isK2) "" else "? super "
749         val wildcard2 = if (isK2) "" else "? extends "
750         check(
751             sourceFiles =
752                 arrayOf(
753                     kotlin(
754                         """
755                         package test.pkg
756 
757                         interface NavGraphBuilder
758 
759                         interface AnimatedContentTransitionScope<S>
760 
761                         interface NavBackStackEntry
762 
763                         interface EnterTransition
764 
765                         fun NavGraphBuilder.after(
766                           enterTransition: (@JvmSuppressWildcards
767                               AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? = null,
768                         ) = TODO()
769 
770                         @Deprecated("no more composable", level = DeprecationLevel.HIDDEN)
771                         fun NavGraphBuilder.before(
772                           enterTransition: (@JvmSuppressWildcards
773                               AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? = null,
774                         ) = TODO()
775                         """
776                     )
777                 ),
778             api =
779                 """
780                 package test.pkg {
781                   public interface AnimatedContentTransitionScope<S> {
782                   }
783                   public interface EnterTransition {
784                   }
785                   public interface NavBackStackEntry {
786                   }
787                   public interface NavGraphBuilder {
788                   }
789                   public final class NavGraphBuilderKt {
790                     method public static Void after(test.pkg.NavGraphBuilder, optional kotlin.jvm.functions.Function1<test.pkg.AnimatedContentTransitionScope<test.pkg.NavBackStackEntry>,test.pkg.EnterTransition?>? enterTransition);
791                     method @Deprecated public static Void before(test.pkg.NavGraphBuilder, optional kotlin.jvm.functions.Function1<${wildcard1}test.pkg.AnimatedContentTransitionScope<test.pkg.NavBackStackEntry>,${wildcard2}test.pkg.EnterTransition?>? enterTransition);
792                   }
793                 }
794                 """
795         )
796     }
797 
798     @Test
Upper bound wildcards -- suspend continuation with generic collectionnull799     fun `Upper bound wildcards -- suspend continuation with generic collection`() {
800         val wildcard = if (isK2) "" else "? extends "
801         check(
802             sourceFiles =
803                 arrayOf(
804                     kotlin(
805                         """
806                         package test.pkg
807 
808                         class Test {
809                           suspend fun foo(): Set<String> {
810                             return setOf("blah")
811                           }
812                         }
813                         """
814                     )
815                 ),
816             api =
817                 """
818                 package test.pkg {
819                   public final class Test {
820                     ctor public Test();
821                     method public suspend Object? foo(kotlin.coroutines.Continuation<? super java.util.Set<${wildcard}java.lang.String>>);
822                   }
823                 }
824                 """
825         )
826     }
827 
828     @Test
boxed type argument as method return typenull829     fun `boxed type argument as method return type`() {
830         // https://youtrack.jetbrains.com/issue/KT-57579
831         check(
832             sourceFiles =
833                 arrayOf(
834                     kotlin(
835                         """
836                         package test.pkg
837                         abstract class ActivityResultContract<I, O> {
838                           abstract fun parseResult(resultCode: Int, intent: Intent?): O
839                         }
840 
841                         interface Intent
842 
843                         class StartActivityForResult : ActivityResultContract<Intent, Boolean>() {
844                           override fun parseResult(resultCode: Int, intent: Intent?): Boolean {
845                             return resultCode == 42
846                           }
847                         }
848                     """
849                     )
850                 ),
851             api =
852                 """
853                 package test.pkg {
854                   public abstract class ActivityResultContract<I, O> {
855                     ctor public ActivityResultContract();
856                     method public abstract O parseResult(int resultCode, test.pkg.Intent? intent);
857                   }
858                   public interface Intent {
859                   }
860                   public final class StartActivityForResult extends test.pkg.ActivityResultContract<test.pkg.Intent,java.lang.Boolean> {
861                     ctor public StartActivityForResult();
862                     method public Boolean parseResult(int resultCode, test.pkg.Intent? intent);
863                   }
864                 }
865             """
866         )
867     }
868 
869     @Test
setter returns this with type castnull870     fun `setter returns this with type cast`() {
871         // https://youtrack.jetbrains.com/issue/KT-61459
872         check(
873             sourceFiles =
874                 arrayOf(
875                     kotlin(
876                         """
877                         package test.pkg
878 
879                         interface Alarm {
880                           interface Builder<Self : Builder<Self>> {
881                             fun build(): Alarm
882                           }
883                         }
884 
885                         abstract class AbstractAlarm<
886                           Self : AbstractAlarm<Self, Builder>, Builder : AbstractAlarm.Builder<Builder, Self>>
887                         internal constructor(
888                           val identifier: String,
889                         ) : Alarm {
890                           abstract class Builder<Self : Builder<Self, Built>, Built : AbstractAlarm<Built, Self>> : Alarm.Builder<Self> {
891                             private var identifier: String = ""
892 
893                             fun setIdentifier(text: String): Self {
894                               this.identifier = text
895                               return this as Self
896                             }
897 
898                             final override fun build(): Built = TODO()
899                           }
900                         }
901                     """
902                     )
903                 ),
904             api =
905                 """
906                 package test.pkg {
907                   public abstract class AbstractAlarm<Self extends test.pkg.AbstractAlarm<Self, Builder>, Builder extends test.pkg.AbstractAlarm.Builder<Builder, Self>> implements test.pkg.Alarm {
908                     method public final String getIdentifier();
909                     property public final String identifier;
910                   }
911                   public abstract static class AbstractAlarm.Builder<Self extends test.pkg.AbstractAlarm.Builder<Self, Built>, Built extends test.pkg.AbstractAlarm<Built, Self>> implements test.pkg.Alarm.Builder<Self> {
912                     ctor public AbstractAlarm.Builder();
913                     method public final Built build();
914                     method public final Self setIdentifier(String text);
915                   }
916                   public interface Alarm {
917                   }
918                   public static interface Alarm.Builder<Self extends test.pkg.Alarm.Builder<Self>> {
919                     method public test.pkg.Alarm build();
920                   }
921                 }
922             """
923         )
924     }
925 
926     @Test
suspend fun in interfacenull927     fun `suspend fun in interface`() {
928         // https://youtrack.jetbrains.com/issue/KT-61544
929         check(
930             sourceFiles =
931                 arrayOf(
932                     kotlin(
933                         """
934                         package test.pkg
935 
936                         interface MyInterface
937 
938                         interface GattClientScope {
939                           suspend fun await(block: () -> Unit)
940                           suspend fun readCharacteristic(p: MyInterface): Result<ByteArray>
941                           suspend fun writeCharacteristic(p: MyInterface, value: ByteArray): Result<Unit>
942                         }
943                         """
944                     )
945                 ),
946             api =
947                 """
948                 package test.pkg {
949                   public interface GattClientScope {
950                     method public suspend Object? await(kotlin.jvm.functions.Function0<kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
951                     method public suspend Object? readCharacteristic(test.pkg.MyInterface p, kotlin.coroutines.Continuation<? super kotlin.Result<? extends byte[]>>);
952                     method public suspend Object? writeCharacteristic(test.pkg.MyInterface p, byte[] value, kotlin.coroutines.Continuation<? super kotlin.Result<? extends kotlin.Unit>>);
953                   }
954                   public interface MyInterface {
955                   }
956                 }
957                 """
958         )
959     }
960 
961     @Test
nullable return type via type aliasnull962     fun `nullable return type via type alias`() {
963         // https://youtrack.jetbrains.com/issue/KT-61460
964         check(
965             sourceFiles =
966                 arrayOf(
967                     kotlin(
968                         """
969                         package test.pkg
970 
971                         typealias HasAuthenticationResultsDelegate = () -> Boolean
972 
973                         class PrepareGetCredentialResponse private constructor(
974                           val hasAuthResultsDelegate: HasAuthenticationResultsDelegate?,
975                         )
976                         """
977                     )
978                 ),
979             api =
980                 """
981                 package test.pkg {
982                   public final class PrepareGetCredentialResponse {
983                     method public kotlin.jvm.functions.Function0<java.lang.Boolean>? getHasAuthResultsDelegate();
984                     property public kotlin.jvm.functions.Function0<java.lang.Boolean>? hasAuthResultsDelegate;
985                   }
986                 }
987             """
988         )
989     }
990 
991     @Test
IntDef with constant in companion objectnull992     fun `IntDef with constant in companion object`() {
993         // https://youtrack.jetbrains.com/issue/KT-61497
994         check(
995             sourceFiles =
996                 arrayOf(
997                     kotlin(
998                         """
999                         package test.pkg
1000 
1001                         @Retention(AnnotationRetention.SOURCE)
1002                         @Target(AnnotationTarget.ANNOTATION_CLASS)
1003                         annotation class MyIntDef(
1004                           vararg val value: Int = [],
1005                           val flag: Boolean = false,
1006                         )
1007 
1008                         class RemoteAuthClient internal constructor(
1009                           private val packageName: String,
1010                         ) {
1011                           companion object {
1012                             const val NO_ERROR: Int = -1
1013                             const val ERROR_UNSUPPORTED: Int = 0
1014                             const val ERROR_PHONE_UNAVAILABLE: Int = 1
1015 
1016                             @MyIntDef(NO_ERROR, ERROR_UNSUPPORTED, ERROR_PHONE_UNAVAILABLE)
1017                             @Retention(AnnotationRetention.SOURCE)
1018                             annotation class ErrorCode
1019                           }
1020                         }
1021                         """
1022                     ),
1023                 ),
1024             api =
1025                 """
1026                 package test.pkg {
1027                   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface MyIntDef {
1028                     method public abstract boolean flag() default false;
1029                     method public abstract int[] value();
1030                     property public abstract boolean flag;
1031                     property public abstract int[] value;
1032                   }
1033                   public final class RemoteAuthClient {
1034                     field public static final test.pkg.RemoteAuthClient.Companion Companion;
1035                     field public static final int ERROR_PHONE_UNAVAILABLE = 1; // 0x1
1036                     field public static final int ERROR_UNSUPPORTED = 0; // 0x0
1037                     field public static final int NO_ERROR = -1; // 0xffffffff
1038                   }
1039                   public static final class RemoteAuthClient.Companion {
1040                     property public static int ERROR_PHONE_UNAVAILABLE;
1041                     property public static int ERROR_UNSUPPORTED;
1042                     property public static int NO_ERROR;
1043                   }
1044                   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @test.pkg.MyIntDef({test.pkg.RemoteAuthClient.NO_ERROR, test.pkg.RemoteAuthClient.ERROR_UNSUPPORTED, test.pkg.RemoteAuthClient.ERROR_PHONE_UNAVAILABLE}) public static @interface RemoteAuthClient.Companion.ErrorCode {
1045                   }
1046                 }
1047                 """
1048         )
1049     }
1050 
1051     @Test
APIs before and after @Deprecated(HIDDEN) on properties or accessorsnull1052     fun `APIs before and after @Deprecated(HIDDEN) on properties or accessors`() {
1053         val api =
1054             if (isK2) {
1055                 // NB: better tracking non-deprecated accessors (thanks to better use-site handling)
1056                 """
1057                     package test.pkg {
1058                       @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface MyAnnotation {
1059                       }
1060                       public interface TestInterface {
1061                         method @Deprecated public int getPOld_deprecatedOnGetter();
1062                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnBoth();
1063                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnGetter();
1064                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnSetter();
1065                         method @Deprecated public int getPOld_deprecatedOnProperty();
1066                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnBoth();
1067                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnGetter();
1068                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnSetter();
1069                         method public int getPOld_deprecatedOnSetter();
1070                         method @test.pkg.MyAnnotation public int getPOld_deprecatedOnSetter_myAnnoOnBoth();
1071                         method @test.pkg.MyAnnotation public int getPOld_deprecatedOnSetter_myAnnoOnGetter();
1072                         method public int getPOld_deprecatedOnSetter_myAnnoOnSetter();
1073                         method public void setPOld_deprecatedOnGetter(int);
1074                         method @test.pkg.MyAnnotation public void setPOld_deprecatedOnGetter_myAnnoOnBoth(int);
1075                         method public void setPOld_deprecatedOnGetter_myAnnoOnGetter(int);
1076                         method @test.pkg.MyAnnotation public void setPOld_deprecatedOnGetter_myAnnoOnSetter(int);
1077                         method @Deprecated public void setPOld_deprecatedOnProperty(int);
1078                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnBoth(int);
1079                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnGetter(int);
1080                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnSetter(int);
1081                         method @Deprecated public void setPOld_deprecatedOnSetter(int);
1082                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnBoth(int);
1083                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnGetter(int);
1084                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnSetter(int);
1085                         property @Deprecated public abstract int pOld_deprecatedOnGetter;
1086                         property @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnBoth;
1087                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnGetter;
1088                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnSetter;
1089                         property @Deprecated public abstract int pOld_deprecatedOnProperty;
1090                         property @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnBoth;
1091                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnGetter;
1092                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnSetter;
1093                         property public abstract int pOld_deprecatedOnSetter;
1094                         property @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnSetter_myAnnoOnBoth;
1095                         property @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnSetter_myAnnoOnGetter;
1096                         property public abstract int pOld_deprecatedOnSetter_myAnnoOnSetter;
1097                       }
1098                       public final class Test_accessors {
1099                         ctor public Test_accessors();
1100                         method public String? getPNew_accessors();
1101                         method @Deprecated public String? getPOld_accessors_deprecatedOnGetter();
1102                         method @Deprecated public String? getPOld_accessors_deprecatedOnProperty();
1103                         method public String? getPOld_accessors_deprecatedOnSetter();
1104                         method public void setPNew_accessors(String?);
1105                         method public void setPOld_accessors_deprecatedOnGetter(String?);
1106                         method @Deprecated public void setPOld_accessors_deprecatedOnProperty(String?);
1107                         method @Deprecated public void setPOld_accessors_deprecatedOnSetter(String?);
1108                         property public String? pNew_accessors;
1109                         property @Deprecated public String? pOld_accessors_deprecatedOnGetter;
1110                         property @Deprecated public String? pOld_accessors_deprecatedOnProperty;
1111                         property public String? pOld_accessors_deprecatedOnSetter;
1112                       }
1113                       public final class Test_getter {
1114                         ctor public Test_getter();
1115                         method public String? getPNew_getter();
1116                         method @Deprecated public String? getPOld_getter_deprecatedOnGetter();
1117                         method @Deprecated public String? getPOld_getter_deprecatedOnProperty();
1118                         method public String? getPOld_getter_deprecatedOnSetter();
1119                         method public void setPNew_getter(String?);
1120                         method public void setPOld_getter_deprecatedOnGetter(String?);
1121                         method @Deprecated public void setPOld_getter_deprecatedOnProperty(String?);
1122                         method @Deprecated public void setPOld_getter_deprecatedOnSetter(String?);
1123                         property public String? pNew_getter;
1124                         property @Deprecated public String? pOld_getter_deprecatedOnGetter;
1125                         property @Deprecated public String? pOld_getter_deprecatedOnProperty;
1126                         property public String? pOld_getter_deprecatedOnSetter;
1127                       }
1128                       public final class Test_noAccessor {
1129                         ctor public Test_noAccessor();
1130                         method public String getPNew_noAccessor();
1131                         method @Deprecated public String getPOld_noAccessor_deprecatedOnGetter();
1132                         method @Deprecated public String getPOld_noAccessor_deprecatedOnProperty();
1133                         method public String getPOld_noAccessor_deprecatedOnSetter();
1134                         method public void setPNew_noAccessor(String);
1135                         method public void setPOld_noAccessor_deprecatedOnGetter(String);
1136                         method @Deprecated public void setPOld_noAccessor_deprecatedOnProperty(String);
1137                         method @Deprecated public void setPOld_noAccessor_deprecatedOnSetter(String);
1138                         property public String pNew_noAccessor;
1139                         property @Deprecated public String pOld_noAccessor_deprecatedOnGetter;
1140                         property @Deprecated public String pOld_noAccessor_deprecatedOnProperty;
1141                         property public String pOld_noAccessor_deprecatedOnSetter;
1142                       }
1143                       public final class Test_setter {
1144                         ctor public Test_setter();
1145                         method public String? getPNew_setter();
1146                         method @Deprecated public String? getPOld_setter_deprecatedOnGetter();
1147                         method @Deprecated public String? getPOld_setter_deprecatedOnProperty();
1148                         method public String? getPOld_setter_deprecatedOnSetter();
1149                         method public void setPNew_setter(String?);
1150                         method public void setPOld_setter_deprecatedOnGetter(String?);
1151                         method @Deprecated public void setPOld_setter_deprecatedOnProperty(String?);
1152                         method @Deprecated public void setPOld_setter_deprecatedOnSetter(String?);
1153                         property public String? pNew_setter;
1154                         property @Deprecated public String? pOld_setter_deprecatedOnGetter;
1155                         property @Deprecated public String? pOld_setter_deprecatedOnProperty;
1156                         property public String? pOld_setter_deprecatedOnSetter;
1157                       }
1158                     }
1159                 """
1160             } else {
1161                 """
1162                     package test.pkg {
1163                       @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface MyAnnotation {
1164                       }
1165                       public interface TestInterface {
1166                         method @Deprecated public int getPOld_deprecatedOnGetter();
1167                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnBoth();
1168                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnGetter();
1169                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnGetter_myAnnoOnSetter();
1170                         method @Deprecated public int getPOld_deprecatedOnProperty();
1171                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnBoth();
1172                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnGetter();
1173                         method @Deprecated @test.pkg.MyAnnotation public int getPOld_deprecatedOnProperty_myAnnoOnSetter();
1174                         method @Deprecated public void setPOld_deprecatedOnProperty(int);
1175                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnBoth(int);
1176                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnGetter(int);
1177                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnProperty_myAnnoOnSetter(int);
1178                         method @Deprecated public void setPOld_deprecatedOnSetter(int);
1179                         method @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnBoth(int);
1180                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnGetter(int);
1181                         method @Deprecated @test.pkg.MyAnnotation public void setPOld_deprecatedOnSetter_myAnnoOnSetter(int);
1182                         property @Deprecated public abstract int pOld_deprecatedOnGetter;
1183                         property @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnBoth;
1184                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnGetter;
1185                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnGetter_myAnnoOnSetter;
1186                         property @Deprecated public abstract int pOld_deprecatedOnProperty;
1187                         property @Deprecated @test.pkg.MyAnnotation @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnBoth;
1188                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnGetter;
1189                         property @Deprecated @test.pkg.MyAnnotation public abstract int pOld_deprecatedOnProperty_myAnnoOnSetter;
1190                         property public abstract int pOld_deprecatedOnSetter;
1191                         property public abstract int pOld_deprecatedOnSetter_myAnnoOnBoth;
1192                         property public abstract int pOld_deprecatedOnSetter_myAnnoOnGetter;
1193                         property public abstract int pOld_deprecatedOnSetter_myAnnoOnSetter;
1194                       }
1195                       public final class Test_accessors {
1196                         ctor public Test_accessors();
1197                         method public String? getPNew_accessors();
1198                         method @Deprecated public String? getPOld_accessors_deprecatedOnGetter();
1199                         method @Deprecated public String? getPOld_accessors_deprecatedOnProperty();
1200                         method public void setPNew_accessors(String?);
1201                         method @Deprecated public void setPOld_accessors_deprecatedOnProperty(String?);
1202                         method @Deprecated public void setPOld_accessors_deprecatedOnSetter(String?);
1203                         property public String? pNew_accessors;
1204                         property @Deprecated public String? pOld_accessors_deprecatedOnGetter;
1205                         property @Deprecated public String? pOld_accessors_deprecatedOnProperty;
1206                         property public String? pOld_accessors_deprecatedOnSetter;
1207                       }
1208                       public final class Test_getter {
1209                         ctor public Test_getter();
1210                         method public String? getPNew_getter();
1211                         method @Deprecated public String? getPOld_getter_deprecatedOnGetter();
1212                         method @Deprecated public String? getPOld_getter_deprecatedOnProperty();
1213                         method public void setPNew_getter(String?);
1214                         method @Deprecated public void setPOld_getter_deprecatedOnProperty(String?);
1215                         method @Deprecated public void setPOld_getter_deprecatedOnSetter(String?);
1216                         property public String? pNew_getter;
1217                         property @Deprecated public String? pOld_getter_deprecatedOnGetter;
1218                         property @Deprecated public String? pOld_getter_deprecatedOnProperty;
1219                         property public String? pOld_getter_deprecatedOnSetter;
1220                       }
1221                       public final class Test_noAccessor {
1222                         ctor public Test_noAccessor();
1223                         method public String getPNew_noAccessor();
1224                         method @Deprecated public String getPOld_noAccessor_deprecatedOnGetter();
1225                         method @Deprecated public String getPOld_noAccessor_deprecatedOnProperty();
1226                         method public void setPNew_noAccessor(String);
1227                         method @Deprecated public void setPOld_noAccessor_deprecatedOnProperty(String);
1228                         method @Deprecated public void setPOld_noAccessor_deprecatedOnSetter(String);
1229                         property public String pNew_noAccessor;
1230                         property @Deprecated public String pOld_noAccessor_deprecatedOnGetter;
1231                         property @Deprecated public String pOld_noAccessor_deprecatedOnProperty;
1232                         property public String pOld_noAccessor_deprecatedOnSetter;
1233                       }
1234                       public final class Test_setter {
1235                         ctor public Test_setter();
1236                         method public String? getPNew_setter();
1237                         method @Deprecated public String? getPOld_setter_deprecatedOnGetter();
1238                         method @Deprecated public String? getPOld_setter_deprecatedOnProperty();
1239                         method public void setPNew_setter(String?);
1240                         method @Deprecated public void setPOld_setter_deprecatedOnProperty(String?);
1241                         method @Deprecated public void setPOld_setter_deprecatedOnSetter(String?);
1242                         property public String? pNew_setter;
1243                         property @Deprecated public String? pOld_setter_deprecatedOnGetter;
1244                         property @Deprecated public String? pOld_setter_deprecatedOnProperty;
1245                         property public String? pOld_setter_deprecatedOnSetter;
1246                       }
1247                     }
1248                 """
1249             }
1250         // TODO: https://youtrack.jetbrains.com/issue/KTIJ-27244
1251         check(
1252             sourceFiles =
1253                 arrayOf(
1254                     kotlin(
1255                         """
1256                         package test.pkg
1257 
1258                         class Test_noAccessor {
1259                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1260                             var pOld_noAccessor_deprecatedOnProperty: String = "42"
1261 
1262                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1263                             var pOld_noAccessor_deprecatedOnGetter: String = "42"
1264 
1265                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1266                             var pOld_noAccessor_deprecatedOnSetter: String = "42"
1267 
1268                             var pNew_noAccessor: String = "42"
1269                         }
1270 
1271                         class Test_getter {
1272                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1273                             var pOld_getter_deprecatedOnProperty: String? = null
1274                                 get() = field ?: "null?"
1275 
1276                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1277                             var pOld_getter_deprecatedOnGetter: String? = null
1278                                 get() = field ?: "null?"
1279 
1280                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1281                             var pOld_getter_deprecatedOnSetter: String? = null
1282                                 get() = field ?: "null?"
1283 
1284                             var pNew_getter: String? = null
1285                                 get() = field ?: "null?"
1286                         }
1287 
1288                         class Test_setter {
1289                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1290                             var pOld_setter_deprecatedOnProperty: String? = null
1291                                 set(value) {
1292                                     if (field == null) {
1293                                         field = value
1294                                     }
1295                                 }
1296 
1297                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1298                             var pOld_setter_deprecatedOnGetter: String? = null
1299                                 set(value) {
1300                                     if (field == null) {
1301                                         field = value
1302                                     }
1303                                 }
1304 
1305                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1306                             var pOld_setter_deprecatedOnSetter: String? = null
1307                                 set(value) {
1308                                     if (field == null) {
1309                                         field = value
1310                                     }
1311                                 }
1312 
1313                             var pNew_setter: String? = null
1314                                 set(value) {
1315                                     if (field == null) {
1316                                         field = value
1317                                     }
1318                                 }
1319                         }
1320 
1321                         class Test_accessors {
1322                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1323                             var pOld_accessors_deprecatedOnProperty: String? = null
1324                                 get() = field ?: "null?"
1325                                 set(value) {
1326                                     if (field == null) {
1327                                         field = value
1328                                     }
1329                                 }
1330 
1331                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1332                             var pOld_accessors_deprecatedOnGetter: String? = null
1333                                 get() = field ?: "null?"
1334                                 set(value) {
1335                                     if (field == null) {
1336                                         field = value
1337                                     }
1338                                 }
1339 
1340                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1341                             var pOld_accessors_deprecatedOnSetter: String? = null
1342                                 get() = field ?: "null?"
1343                                 set(value) {
1344                                     if (field == null) {
1345                                         field = value
1346                                     }
1347                                 }
1348 
1349                             var pNew_accessors: String? = null
1350                                 get() = field ?: "null?"
1351                                 set(value) {
1352                                     if (field == null) {
1353                                         field = value
1354                                     }
1355                                 }
1356                         }
1357 
1358                         @Target(
1359                           AnnotationTarget.PROPERTY,
1360                           AnnotationTarget.PROPERTY_GETTER,
1361                           AnnotationTarget.PROPERTY_SETTER
1362                         )
1363                         annotation class MyAnnotation
1364 
1365                         interface TestInterface {
1366                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1367                             var pOld_deprecatedOnProperty: Int
1368 
1369                             @get:MyAnnotation
1370                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1371                             var pOld_deprecatedOnProperty_myAnnoOnGetter: Int
1372 
1373                             @set:MyAnnotation
1374                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1375                             var pOld_deprecatedOnProperty_myAnnoOnSetter: Int
1376 
1377                             @get:MyAnnotation
1378                             @set:MyAnnotation
1379                             @Deprecated("no more property", level = DeprecationLevel.HIDDEN)
1380                             var pOld_deprecatedOnProperty_myAnnoOnBoth: Int
1381 
1382                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1383                             var pOld_deprecatedOnGetter: Int
1384 
1385                             @get:MyAnnotation
1386                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1387                             var pOld_deprecatedOnGetter_myAnnoOnGetter: Int
1388 
1389                             @set:MyAnnotation
1390                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1391                             var pOld_deprecatedOnGetter_myAnnoOnSetter: Int
1392 
1393                             @get:MyAnnotation
1394                             @set:MyAnnotation
1395                             @get:Deprecated("no more getter", level = DeprecationLevel.HIDDEN)
1396                             var pOld_deprecatedOnGetter_myAnnoOnBoth: Int
1397 
1398                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1399                             var pOld_deprecatedOnSetter: Int
1400 
1401                             @get:MyAnnotation
1402                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1403                             var pOld_deprecatedOnSetter_myAnnoOnGetter: Int
1404 
1405                             @set:MyAnnotation
1406                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1407                             var pOld_deprecatedOnSetter_myAnnoOnSetter: Int
1408 
1409                             @get:MyAnnotation
1410                             @set:MyAnnotation
1411                             @set:Deprecated("no more setter", level = DeprecationLevel.HIDDEN)
1412                             var pOld_deprecatedOnSetter_myAnnoOnBoth: Int
1413                         }
1414                         """
1415                     )
1416                 ),
1417             api = api,
1418         )
1419     }
1420 
1421     @Test
actual typealias -- without value classnull1422     fun `actual typealias -- without value class`() {
1423         // https://youtrack.jetbrains.com/issue/KT-55085
1424         val commonSource =
1425             kotlin(
1426                 "commonMain/src/test/pkg/PointerEvent.kt",
1427                 """
1428                         package test.pkg
1429 
1430                         expect class PointerEvent {
1431                             val keyboardModifiers: PointerKeyboardModifiers
1432                         }
1433 
1434                         expect class NativePointerKeyboardModifiers
1435 
1436                         class PointerKeyboardModifiers(internal val packedValue: NativePointerKeyboardModifiers)
1437                         """
1438             )
1439         val androidSource =
1440             kotlin(
1441                 "androidMain/src/test/pkg/PointerEvent.android.kt",
1442                 """
1443                         package test.pkg
1444 
1445                         actual class PointerEvent {
1446                             actual val keyboardModifiers = PointerKeyboardModifiers(42)
1447                         }
1448 
1449                         internal actual typealias NativePointerKeyboardModifiers = Int
1450                         """
1451             )
1452         check(
1453             sourceFiles = arrayOf(androidSource, commonSource),
1454             projectDescription =
1455                 createProjectDescription(
1456                     createAndroidModuleDescription(arrayOf(androidSource)),
1457                     createCommonModuleDescription(arrayOf(commonSource)),
1458                 ),
1459             api =
1460                 """
1461                 package test.pkg {
1462                   public final class PointerEvent {
1463                     ctor public PointerEvent();
1464                     method public test.pkg.PointerKeyboardModifiers getKeyboardModifiers();
1465                     property public test.pkg.PointerKeyboardModifiers keyboardModifiers;
1466                   }
1467                   public final class PointerKeyboardModifiers {
1468                     ctor public PointerKeyboardModifiers(int packedValue);
1469                   }
1470                 }
1471                 """
1472         )
1473     }
1474 
1475     @Test
actual typealias -- without common splitnull1476     fun `actual typealias -- without common split`() {
1477         // https://youtrack.jetbrains.com/issue/KT-55085
1478         check(
1479             sourceFiles =
1480                 arrayOf(
1481                     kotlin(
1482                         "androidMain/src/test/pkg/PointerEvent.android.kt",
1483                         """
1484                         package test.pkg
1485 
1486                         actual class PointerEvent {
1487                             actual val keyboardModifiers = PointerKeyboardModifiers(42)
1488                         }
1489 
1490                         internal actual typealias NativePointerKeyboardModifiers = Int
1491                         """
1492                     ),
1493                     kotlin(
1494                         "commonMain/src/test/pkg/PointerEvent.kt",
1495                         """
1496                         package test.pkg
1497 
1498                         expect class PointerEvent {
1499                             val keyboardModifiers: PointerKeyboardModifiers
1500                         }
1501 
1502                         expect class NativePointerKeyboardModifiers
1503 
1504                         @kotlin.jvm.JvmInline
1505                         value class PointerKeyboardModifiers(internal val packedValue: NativePointerKeyboardModifiers)
1506                         """
1507                     )
1508                 ),
1509             api =
1510                 """
1511                 package test.pkg {
1512                   public final class PointerEvent {
1513                     ctor public PointerEvent();
1514                     method public int getKeyboardModifiers();
1515                     property public int keyboardModifiers;
1516                   }
1517                   @kotlin.jvm.JvmInline public final value class PointerKeyboardModifiers {
1518                     ctor public PointerKeyboardModifiers(int packedValue);
1519                   }
1520                 }
1521                 """
1522         )
1523     }
1524 
1525     // b/324521456: need to set kotlin-stdlib-common for common module
1526     @FilterByProvider("psi", "k2", action = EXCLUDE)
1527     @Test
actual typealiasnull1528     fun `actual typealias`() {
1529         // https://youtrack.jetbrains.com/issue/KT-55085
1530         // TODO: https://youtrack.jetbrains.com/issue/KTIJ-26853
1531         val typeAliasExpanded = if (isK2) "test.pkg.NativePointerKeyboardModifiers" else "int"
1532         val commonSource =
1533             kotlin(
1534                 "commonMain/src/test/pkg/PointerEvent.kt",
1535                 """
1536                         package test.pkg
1537 
1538                         expect class PointerEvent {
1539                             val keyboardModifiers: PointerKeyboardModifiers
1540                         }
1541 
1542                         expect class NativePointerKeyboardModifiers
1543 
1544                         @kotlin.jvm.JvmInline
1545                         value class PointerKeyboardModifiers(internal val packedValue: NativePointerKeyboardModifiers)
1546                         """
1547             )
1548         val androidSource =
1549             kotlin(
1550                 "androidMain/src/test/pkg/PointerEvent.android.kt",
1551                 """
1552                         package test.pkg
1553 
1554                         actual class PointerEvent {
1555                             actual val keyboardModifiers = PointerKeyboardModifiers(42)
1556                         }
1557 
1558                         internal actual typealias NativePointerKeyboardModifiers = Int
1559                         """
1560             )
1561         check(
1562             sourceFiles = arrayOf(androidSource, commonSource),
1563             projectDescription =
1564                 createProjectDescription(
1565                     createAndroidModuleDescription(arrayOf(androidSource)),
1566                     createCommonModuleDescription(arrayOf(commonSource)),
1567                 ),
1568             api =
1569                 """
1570                 package test.pkg {
1571                   public final class PointerEvent {
1572                     ctor public PointerEvent();
1573                     method public int getKeyboardModifiers();
1574                     property public int keyboardModifiers;
1575                   }
1576                   @kotlin.jvm.JvmInline public final value class PointerKeyboardModifiers {
1577                     ctor public PointerKeyboardModifiers($typeAliasExpanded packedValue);
1578                   }
1579                 }
1580                 """
1581         )
1582     }
1583 
1584     @Test
actual inlinenull1585     fun `actual inline`() {
1586         // b/336816056
1587         val commonSource =
1588             kotlin(
1589                 "commonMain/src/pkg/TestClass.kt",
1590                 """
1591                     package pkg
1592                     public expect class TestClass {
1593                       public fun test1(a: Int = 0)
1594                     }
1595                     public expect inline fun TestClass.test2(a: Int = 0)
1596                 """
1597             )
1598         val androidSource =
1599             kotlin(
1600                 "androidMain/src/pkg/TestClass.kt",
1601                 """
1602                             package pkg
1603                             public actual class TestClass {
1604                               public actual fun test1(a: Int) {}
1605                             }
1606                             public actual inline fun TestClass.test2(a: Int) {
1607                             }
1608                         """
1609             )
1610         check(
1611             sourceFiles = arrayOf(androidSource, commonSource),
1612             projectDescription =
1613                 createProjectDescription(
1614                     createAndroidModuleDescription(arrayOf(androidSource)),
1615                     createCommonModuleDescription(arrayOf(commonSource)),
1616                 ),
1617             api =
1618                 """
1619                 package pkg {
1620                   public final class TestClass {
1621                     ctor public TestClass();
1622                     method public void test1(optional int a);
1623                   }
1624                   public final class TestClassKt {
1625                     method public static inline void test2(pkg.TestClass, optional int a);
1626                   }
1627                 }
1628                 """
1629         )
1630     }
1631 
1632     @Test
JvmDefaultWithCompatibility as typealias actualnull1633     fun `JvmDefaultWithCompatibility as typealias actual`() {
1634         val commonSources =
1635             arrayOf(
1636                 kotlin(
1637                     "commonMain/src/pkg/JvmDefaultWithCompatibility.kt",
1638                     """
1639                     package pkg
1640                     internal expect annotation class JvmDefaultWithCompatibility()
1641                 """
1642                 ),
1643                 kotlin(
1644                     "commonMain/src/pkg2/TestInterface.kt",
1645                     """
1646                     package pkg2
1647 
1648                     import pkg.JvmDefaultWithCompatibility
1649 
1650                     @JvmDefaultWithCompatibility()
1651                     interface TestInterface {
1652                       fun foo()
1653                     }
1654                 """
1655                 ),
1656             )
1657         val androidSource =
1658             kotlin(
1659                 "androidMain/src/pkg/JvmDefaultWithCompatibility.kt",
1660                 """
1661                             package pkg
1662                             internal actual typealias JvmDefaultWithCompatibility = kotlin.jvm.JvmDefaultWithCompatibility
1663                         """
1664             )
1665         check(
1666             sourceFiles = arrayOf(androidSource, *commonSources),
1667             projectDescription =
1668                 createProjectDescription(
1669                     createAndroidModuleDescription(arrayOf(androidSource)),
1670                     createCommonModuleDescription(commonSources),
1671                 ),
1672             api =
1673                 """
1674                 package pkg2 {
1675                   @kotlin.jvm.JvmDefaultWithCompatibility public interface TestInterface {
1676                     method public void foo();
1677                   }
1678                 }
1679                 """
1680         )
1681     }
1682 
1683     @Test
JvmDefaultWithCompatibility as typealias actual using renamed importnull1684     fun `JvmDefaultWithCompatibility as typealias actual using renamed import`() {
1685         val commonSources =
1686             arrayOf(
1687                 kotlin(
1688                     "commonMain/src/pkg/JvmDefaultWithCompatibility.kt",
1689                     """
1690                     package pkg
1691                     internal expect annotation class JvmDefaultWithCompatibility()
1692                 """
1693                 ),
1694                 kotlin(
1695                     "commonMain/src/pkg2/TestInterface.kt",
1696                     """
1697                     package pkg2
1698 
1699                     import pkg.JvmDefaultWithCompatibility
1700 
1701                     @JvmDefaultWithCompatibility
1702                     interface TestInterface {
1703                       fun foo()
1704                     }
1705                 """
1706                 ),
1707             )
1708         val androidSource =
1709             kotlin(
1710                 "androidMain/src/pkg/JvmDefaultWithCompatibility.kt",
1711                 """
1712                             package pkg
1713                             import kotlin.jvm.JvmDefaultWithCompatibility as Compat
1714                             internal actual typealias JvmDefaultWithCompatibility = Compat
1715                         """
1716             )
1717         check(
1718             sourceFiles = arrayOf(androidSource, *commonSources),
1719             projectDescription =
1720                 createProjectDescription(
1721                     createAndroidModuleDescription(arrayOf(androidSource)),
1722                     createCommonModuleDescription(commonSources),
1723                 ),
1724             api =
1725                 """
1726                 package pkg2 {
1727                   @kotlin.jvm.JvmDefaultWithCompatibility public interface TestInterface {
1728                     method public void foo();
1729                   }
1730                 }
1731                 """
1732         )
1733     }
1734 
1735     @Test
JvmDefaultWithCompatibility as typealias actual using chained typealiasesnull1736     fun `JvmDefaultWithCompatibility as typealias actual using chained typealiases`() {
1737         val commonSources =
1738             arrayOf(
1739                 kotlin(
1740                     "commonMain/src/pkg/JvmDefaultWithCompatibility.kt",
1741                     """
1742                     package pkg
1743                     internal expect annotation class JvmDefaultWithCompatibility()
1744                 """
1745                 ),
1746                 kotlin(
1747                     "commonMain/src/pkg2/TestInterface.kt",
1748                     """
1749                     package pkg2
1750 
1751                     import pkg.JvmDefaultWithCompatibility
1752 
1753                     @JvmDefaultWithCompatibility
1754                     interface TestInterface {
1755                       fun foo()
1756                     }
1757                 """
1758                 ),
1759             )
1760         val androidSource =
1761             kotlin(
1762                 "androidMain/src/pkg/JvmDefaultWithCompatibility.kt",
1763                 """
1764                             package pkg
1765                             private typealias Compat = kotlin.jvm.JvmDefaultWithCompatibility
1766                             internal actual typealias JvmDefaultWithCompatibility = Compat
1767                         """
1768             )
1769         check(
1770             sourceFiles = arrayOf(androidSource, *commonSources),
1771             projectDescription =
1772                 createProjectDescription(
1773                     createAndroidModuleDescription(arrayOf(androidSource)),
1774                     createCommonModuleDescription(commonSources),
1775                 ),
1776             api =
1777                 """
1778                 package pkg2 {
1779                   @kotlin.jvm.JvmDefaultWithCompatibility public interface TestInterface {
1780                     method public void foo();
1781                   }
1782                 }
1783                 """
1784         )
1785     }
1786 
1787     @Test
internal value class extension propertynull1788     fun `internal value class extension property`() {
1789         // b/385148821
1790         check(
1791             sourceFiles =
1792                 arrayOf(
1793                     kotlin(
1794                         """
1795                             package test.pkg
1796                             @JvmInline
1797                             value class IntValue(val value: Int)
1798                             internal var IntValue.isValid
1799                                 get() = this.value != 0
1800                                 set(newValue) = Unit
1801                         """
1802                     )
1803                 ),
1804             api =
1805                 """
1806             package test.pkg {
1807               @kotlin.jvm.JvmInline public final value class IntValue {
1808                 ctor public IntValue(int value);
1809                 method public int getValue();
1810                 property public int value;
1811               }
1812             }
1813             """
1814         )
1815     }
1816 
1817     @Test
default parameter value from common, with android=false for commonnull1818     fun `default parameter value from common, with android=false for common`() {
1819         val commonSource =
1820             kotlin(
1821                 "commonMain/src/test/pkg/Foo.kt",
1822                 """
1823                     package test.pkg
1824                     expect class Foo {
1825                         expect fun foo(i: Int = 0): Int
1826                     }
1827                 """
1828             )
1829         val androidSource =
1830             kotlin(
1831                 "androidMain/src/test/pkg/JvmDefaultWithCompatibility.kt",
1832                 """
1833                     package test.pkg
1834                     actual class Foo {
1835                         actual fun foo(i: Int) = i
1836                     }
1837                 """
1838             )
1839         check(
1840             sourceFiles = arrayOf(androidSource, commonSource),
1841             projectDescription =
1842                 createProjectDescription(
1843                     createAndroidModuleDescription(arrayOf(androidSource)),
1844                     createCommonModuleDescription(arrayOf(commonSource)),
1845                 ),
1846             api =
1847                 """
1848                     package test.pkg {
1849                       public final class Foo {
1850                         ctor public Foo();
1851                         method public int foo(optional int i);
1852                       }
1853                     }
1854                 """
1855         )
1856     }
1857 
1858     @Test
default parameter value from common, with android=true for commonnull1859     fun `default parameter value from common, with android=true for common`() {
1860         // b/322156458
1861         val modifier =
1862             if (isK2) {
1863                 ""
1864             } else {
1865                 "optional "
1866             }
1867         val commonSource =
1868             kotlin(
1869                 "commonMain/src/test/pkg/Foo.kt",
1870                 """
1871                     package test.pkg
1872                     expect class Foo {
1873                         expect fun foo(i: Int = 0): Int
1874                     }
1875                 """
1876             )
1877         val androidSource =
1878             kotlin(
1879                 "androidMain/src/test/pkg/JvmDefaultWithCompatibility.kt",
1880                 """
1881                     package test.pkg
1882                     actual class Foo {
1883                         actual fun foo(i: Int) = i
1884                     }
1885                 """
1886             )
1887         check(
1888             sourceFiles = arrayOf(androidSource, commonSource),
1889             projectDescription =
1890                 createProjectDescription(
1891                     createAndroidModuleDescription(arrayOf(androidSource)),
1892                     createModuleDescription(
1893                         moduleName = "commonMain",
1894                         android = true,
1895                         sourceFiles = arrayOf(commonSource),
1896                         dependsOn = emptyList()
1897                     ),
1898                 ),
1899             api =
1900                 """
1901                     package test.pkg {
1902                       public final class Foo {
1903                         ctor public Foo();
1904                         method public int foo(${modifier}int i);
1905                       }
1906                     }
1907                 """
1908         )
1909     }
1910 
1911     @Test
Vararg parameter followed by value class type parameternull1912     fun `Vararg parameter followed by value class type parameter`() {
1913         check(
1914             sourceFiles =
1915                 arrayOf(
1916                     kotlin(
1917                         """
1918                         package test.pkg
1919                         fun foo(vararg varargParam: String, valueParam: IntValue) = Unit
1920                         @JvmInline
1921                         value class IntValue(val value: Int)
1922                     """
1923                     )
1924                 ),
1925             api =
1926                 """
1927                 package test.pkg {
1928                   @kotlin.jvm.JvmInline public final value class IntValue {
1929                     ctor public IntValue(int value);
1930                     method public int getValue();
1931                     property public int value;
1932                   }
1933                   public final class IntValueKt {
1934                     method public static void foo(String[] varargParam, int valueParam);
1935                   }
1936                 }
1937             """
1938         )
1939     }
1940 
1941     @Test
Data class with value class typenull1942     fun `Data class with value class type`() {
1943         // b/388244267
1944         val copySuffix =
1945             if (isK2) {
1946                 ""
1947             } else {
1948                 "-Vxmw0xk"
1949             }
1950         check(
1951             sourceFiles =
1952                 arrayOf(
1953                     kotlin(
1954                         """
1955                         package test.pkg
1956                         @JvmInline
1957                         value class IntValue(val value: Int)
1958                         data class IntValueData(private val intValue: IntValue)
1959                     """
1960                     )
1961                 ),
1962             api =
1963                 """
1964                 package test.pkg {
1965                   @kotlin.jvm.JvmInline public final value class IntValue {
1966                     ctor public IntValue(int value);
1967                     method public int getValue();
1968                     property public int value;
1969                   }
1970                   public final class IntValueData {
1971                     ctor public IntValueData(int intValue);
1972                     method public test.pkg.IntValueData copy$copySuffix(int intValue);
1973                   }
1974                 }
1975             """
1976         )
1977     }
1978 
1979     @Test
Private property with defined getter of value class typenull1980     fun `Private property with defined getter of value class type`() {
1981         // b/388494377
1982         check(
1983             sourceFiles =
1984                 arrayOf(
1985                     kotlin(
1986                         """
1987                         package test.pkg.main
1988                         class Foo {
1989                             private var privateVar: IntValue
1990                                 get() = IntValue(0)
1991                                 set(newValue) = Unit
1992                         }
1993                         @JvmInline
1994                         internal value class IntValue(val value: Int)
1995                     """
1996                     ),
1997                 ),
1998             api =
1999                 """
2000                 package test.pkg.main {
2001                   public final class Foo {
2002                     ctor public Foo();
2003                   }
2004                 }
2005                 """
2006         )
2007     }
2008 
2009     @Test
Repeatable annotation with expect actualnull2010     fun `Repeatable annotation with expect actual`() {
2011         // b/399105459
2012         val commonSource =
2013             kotlin(
2014                 "commonMain/src/test/pkg/AnnotationCanRepeat.kt",
2015                 """
2016                     package test.pkg
2017                     @Repeatable
2018                     expect annotation class AnnotationCanRepeat(val value: Int)
2019                 """
2020             )
2021         val androidSource =
2022             kotlin(
2023                 "androidMain/src/test/pkg/AnnotationCanRepeat.android.kt",
2024                 """
2025                     package test.pkg
2026                     @JvmRepeatable(AnnotationCanRepeat.Entries::class)
2027                     actual annotation class AnnotationCanRepeat
2028                     actual constructor(actual val value: Int) {
2029                         annotation class Entries(vararg val value: AnnotationCanRepeat)
2030                     }
2031                 """
2032             )
2033         check(
2034             sourceFiles = arrayOf(commonSource, androidSource),
2035             projectDescription =
2036                 createProjectDescription(
2037                     createCommonModuleDescription(arrayOf(commonSource)),
2038                     createAndroidModuleDescription(arrayOf(androidSource))
2039                 ),
2040             api =
2041                 """
2042                 package test.pkg {
2043                   @java.lang.annotation.Repeatable(AnnotationCanRepeat.Entries::class) public @interface AnnotationCanRepeat {
2044                     method public abstract int value();
2045                     property public abstract int value;
2046                   }
2047                   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface AnnotationCanRepeat.Entries {
2048                     method public abstract test.pkg.AnnotationCanRepeat[] value();
2049                     property public abstract test.pkg.AnnotationCanRepeat[] value;
2050                   }
2051                 }
2052                 """
2053         )
2054     }
2055 }
2056