aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiaxiang Chen <jiaxiang@google.com>2024-01-31 17:57:50 -0800
committerKSP Auto Pick <kotlin-symbol-processing@google.com>2024-02-27 02:26:58 +0000
commitf7b15c3b2d776eb73aa92f83de647701095d8c44 (patch)
treed39ddc8f60c40e4ea63344c5d73d4d13218b067b
parent9d790e07382c370ab8feb165aa2492d75b0d4872 (diff)
downloadksp-f7b15c3b2d776eb73aa92f83de647701095d8c44.tar.gz
implement getJavaWildcard for KSP2
(cherry picked from commit c56396b51282b311e2bf81426599e3b12ff172e8)
-rw-r--r--common-util/src/main/kotlin/com/google/devtools/ksp/common/impl/RefPosition.kt73
-rw-r--r--compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt65
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt39
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt136
-rw-r--r--kotlin-analysis-api/testData/javaWildcards2.kt114
-rw-r--r--test-utils/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt3
6 files changed, 366 insertions, 64 deletions
diff --git a/common-util/src/main/kotlin/com/google/devtools/ksp/common/impl/RefPosition.kt b/common-util/src/main/kotlin/com/google/devtools/ksp/common/impl/RefPosition.kt
new file mode 100644
index 00000000..85e9565b
--- /dev/null
+++ b/common-util/src/main/kotlin/com/google/devtools/ksp/common/impl/RefPosition.kt
@@ -0,0 +1,73 @@
+package com.google.devtools.ksp.common.impl
+
+import com.google.devtools.ksp.symbol.ClassKind
+import com.google.devtools.ksp.symbol.KSCallableReference
+import com.google.devtools.ksp.symbol.KSClassDeclaration
+import com.google.devtools.ksp.symbol.KSFunctionDeclaration
+import com.google.devtools.ksp.symbol.KSNode
+import com.google.devtools.ksp.symbol.KSPropertyDeclaration
+import com.google.devtools.ksp.symbol.KSPropertyGetter
+import com.google.devtools.ksp.symbol.KSReferenceElement
+import com.google.devtools.ksp.symbol.KSTypeArgument
+import com.google.devtools.ksp.symbol.KSTypeReference
+
+enum class RefPosition {
+ PARAMETER_TYPE,
+ RETURN_TYPE,
+ SUPER_TYPE
+}
+
+// TODO: Strict mode for catching unhandled cases.
+fun findRefPosition(ref: KSTypeReference): RefPosition = when (val parent = ref.parent) {
+ is KSCallableReference -> when (ref) {
+ parent.returnType -> RefPosition.RETURN_TYPE
+ else -> RefPosition.PARAMETER_TYPE
+ }
+ is KSFunctionDeclaration -> when (ref) {
+ parent.returnType -> RefPosition.RETURN_TYPE
+ else -> RefPosition.PARAMETER_TYPE
+ }
+ is KSPropertyGetter -> RefPosition.RETURN_TYPE
+ is KSPropertyDeclaration -> when (ref) {
+ parent.type -> RefPosition.RETURN_TYPE
+ else -> RefPosition.PARAMETER_TYPE
+ }
+ is KSClassDeclaration -> RefPosition.SUPER_TYPE
+ // is KSTypeArgument -> RefPosition.PARAMETER_TYPE
+ // is KSAnnotation -> RefPosition.PARAMETER_TYPE
+ // is KSTypeAlias -> RefPosition.PARAMETER_TYPE
+ // is KSValueParameter -> RefPosition.PARAMETER_TYPE
+ // is KSTypeParameter -> RefPosition.PARAMETER_TYPE
+ else -> RefPosition.PARAMETER_TYPE
+}
+
+// Search in self and parents for the first type reference that is not part of a type argument.
+fun KSTypeReference.findOuterMostRef(): Pair<KSTypeReference, List<Int>> {
+ fun KSNode.findParentRef(): KSTypeReference? {
+ var parent = parent
+ while (parent != null && parent !is KSTypeReference)
+ parent = parent.parent
+ return parent as? KSTypeReference
+ }
+
+ val fallback = Pair<KSTypeReference, List<Int>>(this, emptyList())
+ val indexes = mutableListOf<Int>()
+ var candidate: KSTypeReference = this
+ // KSTypeArgument's parent can be either KSReferenceElement or KSType.
+ while (candidate.parent is KSTypeArgument) {
+ // If the parent is a KSType, it's a synthetic reference.
+ // Do nothing and reply on the fallback behavior.
+ val referenceElement = (candidate.parent!!.parent as? KSReferenceElement) ?: return fallback
+ indexes.add(referenceElement.typeArguments.indexOf(candidate.parent))
+ // In case the program isn't properly structured, fallback.
+ candidate = referenceElement.findParentRef() ?: return fallback
+ }
+ return Pair(candidate, indexes)
+}
+
+fun KSTypeReference.isReturnTypeOfAnnotationMethod(): Boolean {
+ var candidate = this.parent
+ while (candidate !is KSClassDeclaration && candidate != null)
+ candidate = candidate.parent
+ return (candidate as? KSClassDeclaration)?.classKind == ClassKind.ANNOTATION_CLASS
+}
diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
index 2efdc42b..2a559dcc 100644
--- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
+++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
@@ -28,6 +28,10 @@ import com.google.devtools.ksp.common.JVM_VOLATILE_ANNOTATION_FQN
import com.google.devtools.ksp.common.extractThrowsAnnotation
import com.google.devtools.ksp.common.impl.KSNameImpl
import com.google.devtools.ksp.common.impl.KSTypeReferenceSyntheticImpl
+import com.google.devtools.ksp.common.impl.RefPosition
+import com.google.devtools.ksp.common.impl.findOuterMostRef
+import com.google.devtools.ksp.common.impl.findRefPosition
+import com.google.devtools.ksp.common.impl.isReturnTypeOfAnnotationMethod
import com.google.devtools.ksp.common.javaModifiers
import com.google.devtools.ksp.common.memoized
import com.google.devtools.ksp.common.visitor.CollectAnnotatedSymbolsVisitor
@@ -1232,67 +1236,6 @@ class ResolverImpl(
return modifiers
}
- private enum class RefPosition {
- PARAMETER_TYPE,
- RETURN_TYPE,
- SUPER_TYPE
- }
-
- // Search in self and parents for the first type reference that is not part of a type argument.
- private fun KSTypeReference.findOuterMostRef(): Pair<KSTypeReference, List<Int>> {
- fun KSNode.findParentRef(): KSTypeReference? {
- var parent = parent
- while (parent != null && parent !is KSTypeReference)
- parent = parent.parent
- return parent as? KSTypeReference
- }
-
- val fallback = Pair<KSTypeReference, List<Int>>(this, emptyList())
- val indexes = mutableListOf<Int>()
- var candidate: KSTypeReference = this
- // KSTypeArgument's parent can be either KSReferenceElement or KSType.
- while (candidate.parent is KSTypeArgument) {
- // If the parent is a KSType, it's a synthetic reference.
- // Do nothing and reply on the fallback behavior.
- val referenceElement = (candidate.parent!!.parent as? KSReferenceElement) ?: return fallback
- indexes.add(referenceElement.typeArguments.indexOf(candidate.parent))
- // In case the program isn't properly structured, fallback.
- candidate = referenceElement.findParentRef() ?: return fallback
- }
- return Pair(candidate, indexes)
- }
-
- // TODO: Strict mode for catching unhandled cases.
- private fun findRefPosition(ref: KSTypeReference): RefPosition = when (val parent = ref.parent) {
- is KSCallableReference -> when (ref) {
- parent.returnType -> RefPosition.RETURN_TYPE
- else -> RefPosition.PARAMETER_TYPE
- }
- is KSFunctionDeclaration -> when (ref) {
- parent.returnType -> RefPosition.RETURN_TYPE
- else -> RefPosition.PARAMETER_TYPE
- }
- is KSPropertyGetter -> RefPosition.RETURN_TYPE
- is KSPropertyDeclaration -> when (ref) {
- parent.type -> RefPosition.RETURN_TYPE
- else -> RefPosition.PARAMETER_TYPE
- }
- is KSClassDeclaration -> RefPosition.SUPER_TYPE
- // is KSTypeArgument -> RefPosition.PARAMETER_TYPE
- // is KSAnnotation -> RefPosition.PARAMETER_TYPE
- // is KSTypeAlias -> RefPosition.PARAMETER_TYPE
- // is KSValueParameter -> RefPosition.PARAMETER_TYPE
- // is KSTypeParameter -> RefPosition.PARAMETER_TYPE
- else -> RefPosition.PARAMETER_TYPE
- }
-
- private fun KSTypeReference.isReturnTypeOfAnnotationMethod(): Boolean {
- var candidate = this.parent
- while (candidate !is KSClassDeclaration && candidate != null)
- candidate = candidate.parent
- return (candidate as? KSClassDeclaration)?.classKind == ClassKind.ANNOTATION_CLASS
- }
-
// Convert type arguments for Java wildcard, recursively.
private fun KotlinType.toWildcard(mode: TypeMappingMode): KotlinType? {
val parameters = constructor.parameters
diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt
index 0c9f15ed..a6e640be 100644
--- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt
+++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt
@@ -29,6 +29,10 @@ import com.google.devtools.ksp.common.JVM_VOLATILE_ANNOTATION_FQN
import com.google.devtools.ksp.common.extractThrowsAnnotation
import com.google.devtools.ksp.common.impl.KSNameImpl
import com.google.devtools.ksp.common.impl.KSTypeReferenceSyntheticImpl
+import com.google.devtools.ksp.common.impl.RefPosition
+import com.google.devtools.ksp.common.impl.findOuterMostRef
+import com.google.devtools.ksp.common.impl.findRefPosition
+import com.google.devtools.ksp.common.impl.isReturnTypeOfAnnotationMethod
import com.google.devtools.ksp.common.javaModifiers
import com.google.devtools.ksp.common.memoized
import com.google.devtools.ksp.common.visitor.CollectAnnotatedSymbolsVisitor
@@ -57,11 +61,16 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
+import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCliJavaFileManagerImpl
import org.jetbrains.kotlin.fir.types.isRaw
+import org.jetbrains.kotlin.fir.types.typeContext
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
+import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
+import org.jetbrains.kotlin.load.kotlin.getOptimalModeForReturnType
+import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -357,7 +366,35 @@ class ResolverAAImpl(
}
override fun getJavaWildcard(reference: KSTypeReference): KSTypeReference {
- TODO("Not yet implemented")
+ val (ref, indexes) = reference.findOuterMostRef()
+ val type = ref.resolve()
+ if (type.isError)
+ return reference
+ val position = findRefPosition(ref)
+ val ktType = (type as KSTypeImpl).type
+ // cast to FIR internal needed due to missing support in AA for type mapping mode
+ // and corresponding type mapping APIs.
+ val coneType = (ktType as KtFirType).coneType
+ val mode = analyze {
+ val typeContext = analyze { useSiteModule.getFirResolveSession(project).useSiteFirSession.typeContext }
+ when (position) {
+ RefPosition.RETURN_TYPE -> typeContext.getOptimalModeForReturnType(
+ coneType,
+ reference.isReturnTypeOfAnnotationMethod()
+ )
+ RefPosition.SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
+ RefPosition.PARAMETER_TYPE -> typeContext.getOptimalModeForValueParameter(coneType)
+ }.updateFromParents(ref)
+ }
+ return analyze {
+ ktType.toWildcard(mode)?.let {
+ var candidate: KtType = it
+ for (i in indexes.reversed()) {
+ candidate = candidate.typeArguments()[i].type!!
+ }
+ KSTypeReferenceSyntheticImpl.getCached(KSTypeImpl.getCached(candidate), null)
+ }
+ } ?: reference
}
override fun getJvmCheckedException(accessor: KSPropertyAccessor): Sequence<KSType> {
diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt
index a3c38cb3..5b711bc6 100644
--- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt
+++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt
@@ -40,27 +40,33 @@ import org.jetbrains.kotlin.analysis.api.components.buildClassType
import org.jetbrains.kotlin.analysis.api.components.buildTypeParameterType
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirValueParameterSymbol
+import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.lifetime.KtAlwaysAccessibleLifetimeToken
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
+import org.jetbrains.kotlin.codegen.state.JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME
+import org.jetbrains.kotlin.codegen.state.JVM_WILDCARD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.toFirExpression
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
+import org.jetbrains.kotlin.fir.types.isAny
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryClassSignatureParser
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaAnnotationVisitor
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.ClassifierResolutionContext
+import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.types.Variance
+import org.jetbrains.kotlin.types.getEffectiveVariance
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.ClassReader
@@ -566,3 +572,133 @@ internal fun KtType.replace(newArgs: List<KtTypeProjection>): KtType? {
}
}
}
+internal fun getVarianceForWildcard(
+ parameter: KtTypeParameterSymbol,
+ projection: KtTypeProjection,
+ mode: TypeMappingMode
+): Variance {
+ val projectionKind = if (projection is KtTypeArgumentWithVariance) {
+ projection.variance
+ } else {
+ Variance.INVARIANT
+ }
+ val parameterVariance = parameter.variance
+ if (parameterVariance == Variance.INVARIANT) {
+ return projectionKind
+ }
+ if (mode.skipDeclarationSiteWildcards) {
+ return Variance.INVARIANT
+ }
+ if (projectionKind == Variance.INVARIANT || projectionKind == parameterVariance) {
+ if (mode.skipDeclarationSiteWildcardsIfPossible && projection !is KtStarTypeProjection) {
+ val coneType = (projection.type as KtFirType).coneType
+ // TODO: fix most precise covariant argument case.
+ if (parameterVariance == Variance.OUT_VARIANCE) {
+ return Variance.INVARIANT
+ }
+ if (parameterVariance == Variance.IN_VARIANCE && coneType.isAny) {
+ return Variance.INVARIANT
+ }
+ }
+ return parameterVariance
+ }
+ return Variance.OUT_VARIANCE
+}
+
+internal fun KtType.toWildcard(mode: TypeMappingMode): KtType {
+ val parameters = this.classifierSymbol()?.typeParameters ?: emptyList()
+ val args = this.typeArguments()
+ return analyze {
+ when (this@toWildcard) {
+ is KtClassType -> {
+ // TODO: missing annotations from original type.
+ buildClassType(this@toWildcard.expandedClassSymbol!!) {
+ parameters.zip(args).map { (param, arg) ->
+ val argMode = mode.updateFromAnnotations(arg.type)
+ val variance = getVarianceForWildcard(param, arg, argMode)
+ val genericMode = argMode.toGenericArgumentMode(
+ getEffectiveVariance(
+ param.variance,
+ (arg as? KtTypeArgumentWithVariance)?.variance ?: Variance.INVARIANT
+ )
+ )
+ val argType =
+ arg.type ?: analysisSession.builtinTypes.ANY.withNullability(KtTypeNullability.NULLABLE)
+ argument(argType.toWildcard(genericMode), variance)
+ }
+ nullability = this@toWildcard.nullability
+ }
+ }
+ is KtTypeParameterType -> {
+ buildTypeParameterType(this@toWildcard.symbol)
+ }
+ else -> throw IllegalStateException("Unexpected type ${this@toWildcard}")
+ }
+ }
+}
+
+internal fun TypeMappingMode.suppressJvmWildcards(
+ suppress: Boolean
+): TypeMappingMode {
+ return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
+ skipDeclarationSiteWildcards = suppress,
+ isForAnnotationParameter = isForAnnotationParameter,
+ needInlineClassWrapping = needInlineClassWrapping,
+ mapTypeAliases = mapTypeAliases
+ )
+}
+internal fun TypeMappingMode.updateFromParents(
+ ref: KSTypeReference
+): TypeMappingMode {
+ return ref.findJvmSuppressWildcards()?.let {
+ this.suppressJvmWildcards(it)
+ } ?: this
+}
+
+internal fun KSTypeReference.findJvmSuppressWildcards(): Boolean? {
+ var candidate: KSNode? = this
+ while (candidate != null) {
+ if ((candidate is KSTypeReference || candidate is KSDeclaration)) {
+ (candidate as KSAnnotated).annotations.singleOrNull {
+ it.annotationType.resolve().declaration.qualifiedName?.asString()?.equals(
+ JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME.asString()
+ ) == true
+ }?.let { it.arguments.singleOrNull { it.name?.asString() == "suppress" } }?.let {
+ return it.value as? Boolean
+ }
+ }
+ candidate = candidate.parent
+ }
+ return null
+}
+
+internal fun TypeMappingMode.updateFromAnnotations(
+ type: KtType?
+): TypeMappingMode {
+ if (type == null) {
+ return this
+ }
+ type.annotations().firstOrNull {
+ it.annotationType.resolve().declaration.qualifiedName?.asString()
+ ?.equals(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME.asString()) == true
+ }?.let {
+ it.arguments.firstOrNull { it.name?.asString() == "suppress" }?.let {
+ (it.value as? Boolean)?.let { return suppressJvmWildcards(it) } ?: return this
+ }
+ }
+ return if (type.annotations().any {
+ it.annotationType.resolve().declaration.qualifiedName?.asString()
+ ?.equals(JVM_WILDCARD_ANNOTATION_FQ_NAME.asString()) == true
+ }
+ ) {
+ TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
+ skipDeclarationSiteWildcards = false,
+ isForAnnotationParameter = isForAnnotationParameter,
+ fallbackMode = this,
+ needInlineClassWrapping = needInlineClassWrapping,
+ mapTypeAliases = mapTypeAliases
+ )
+ } else {
+ this
+ }
+}
diff --git a/kotlin-analysis-api/testData/javaWildcards2.kt b/kotlin-analysis-api/testData/javaWildcards2.kt
new file mode 100644
index 00000000..068dd3cc
--- /dev/null
+++ b/kotlin-analysis-api/testData/javaWildcards2.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2024 Google LLC
+ * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// WITH_RUNTIME
+// TEST PROCESSOR: JavaWildcard2Processor
+// EXPECTED:
+// MyEnum : Enum<MyEnum>
+// <init> : MyEnum
+// values : Array<MyEnum>
+// value : String
+// valueOf : MyEnum
+// entries : EnumEntries<MyEnum>
+// entries.getter() : EnumEntries<MyEnum>
+// VarianceSubjectSuppressed : Any
+// R : Any?
+// propWithFinalType : String
+// propWithFinalType.getter() : String
+// <set-?> : String
+// propWithOpenType : Number
+// propWithOpenType.getter() : Number
+// <set-?> : Number
+// propWithFinalGeneric : List<String>
+// propWithFinalGeneric.getter() : List<String>
+// <set-?> : List<String>
+// propWithOpenGeneric : List<Number>
+// propWithOpenGeneric.getter() : List<Number>
+// <set-?> : List<Number>
+// propWithTypeArg : R
+// propWithTypeArg.getter() : R
+// <set-?> : R
+// propWithTypeArgGeneric : List<R>
+// propWithTypeArgGeneric.getter() : List<R>
+// <set-?> : List<R>
+// propWithOpenTypeButSuppressAnnotation : Number
+// propWithOpenTypeButSuppressAnnotation.getter() : Number
+// <set-?> : Number
+// list2 : List<Any?>
+// list1 : List<Any?>
+// list3 : List<R>
+// listTypeArg : List<R>
+// list4 : List<Number>
+// listTypeArgNumber : List<Number>
+// list5 : List<String>
+// listTypeArgString : List<String>
+// list6 : List<MyEnum>
+// listTypeArgEnum : List<MyEnum>
+// list7 : List<out String>
+// explicitJvmWildcard : List<out String>
+// list8 : List<Number>
+// explicitJvmSuppressWildcard_OnType : List<Number>
+// list9 : List<Number>
+// explicitJvmSuppressWildcard_OnType2 : List<Number>
+// starList : List<Any?>
+// typeArgList : List<R>
+// numberList : List<Number>
+// stringList : List<String>
+// enumList : List<MyEnum>
+// jvmWildcard : List<out String>
+// suppressJvmWildcard : List<Number>
+// <init> : VarianceSubjectSuppressed<Any?>
+// R : Any?
+// END
+
+enum class MyEnum()
+
+@JvmSuppressWildcards
+class VarianceSubjectSuppressed<R>(
+ starList: List<*>,
+ typeArgList: List<R>,
+ numberList: List<Number>,
+ stringList: List<String>,
+ enumList: List<MyEnum>,
+ jvmWildcard: List<@JvmWildcard String>,
+ suppressJvmWildcard: List<@JvmSuppressWildcards Number>
+) {
+ var propWithFinalType: String = ""
+ var propWithOpenType: Number = 3
+ var propWithFinalGeneric: List<String> = TODO()
+ var propWithOpenGeneric: List<Number> = TODO()
+ var propWithTypeArg: R = TODO()
+ var propWithTypeArgGeneric: List<R> = TODO()
+ @JvmSuppressWildcards
+ var propWithOpenTypeButSuppressAnnotation: Number = 3
+ fun list1(list2: List<*>): List<*> { TODO() }
+ fun listTypeArg(list3: List<R>): List<R> { TODO() }
+ fun listTypeArgNumber(list4: List<Number>): List<Number> { TODO() }
+ fun listTypeArgString(list5: List<String>): List<String> { TODO() }
+ fun listTypeArgEnum(list6: List<MyEnum>): List<MyEnum> { TODO() }
+ fun explicitJvmWildcard(
+ list7: List<@JvmWildcard String>
+ ): List<@JvmWildcard String> { TODO() }
+
+ fun explicitJvmSuppressWildcard_OnType(
+ list8: List<@JvmSuppressWildcards Number>
+ ): List<@JvmSuppressWildcards Number> { TODO() }
+
+ fun explicitJvmSuppressWildcard_OnType2(
+ list9: @JvmSuppressWildcards List<Number>
+ ): @JvmSuppressWildcards List<Number> { TODO() }
+}
diff --git a/test-utils/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt b/test-utils/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt
index 37301f62..9d6bbc8e 100644
--- a/test-utils/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt
+++ b/test-utils/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt
@@ -352,11 +352,10 @@ class KSPAATest : AbstractKSPAATest() {
runTest("../test-utils/testData/api/javaTypes2.kt")
}
- @Disabled
@TestMetadata("javaWildcards2.kt")
@Test
fun testJavaWildcards2() {
- runTest("../test-utils/testData/api/javaWildcards2.kt")
+ runTest("../kotlin-analysis-api/testData/javaWildcards2.kt")
}
@TestMetadata("lateinitProperties.kt")