Write version requirement on inline classes and relevant declarations
#KT-26720 Fixed
This commit is contained in:
+64
-14
@@ -33,9 +33,11 @@ import org.jetbrains.kotlin.resolve.constants.IntValue
|
|||||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class DescriptorSerializer private constructor(
|
class DescriptorSerializer private constructor(
|
||||||
@@ -145,6 +147,8 @@ class DescriptorSerializer private constructor(
|
|||||||
|
|
||||||
extension.serializeClass(classDescriptor, builder, versionRequirementTable)
|
extension.serializeClass(classDescriptor, builder, versionRequirementTable)
|
||||||
|
|
||||||
|
writeVersionRequirementForInlineClasses(classDescriptor, builder, versionRequirementTable)
|
||||||
|
|
||||||
val versionRequirementTableProto = versionRequirementTable.serialize()
|
val versionRequirementTableProto = versionRequirementTable.serialize()
|
||||||
if (versionRequirementTableProto != null) {
|
if (versionRequirementTableProto != null) {
|
||||||
builder.versionRequirementTable = versionRequirementTableProto
|
builder.versionRequirementTable = versionRequirementTableProto
|
||||||
@@ -152,6 +156,28 @@ class DescriptorSerializer private constructor(
|
|||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun writeVersionRequirementForInlineClasses(
|
||||||
|
classDescriptor: ClassDescriptor,
|
||||||
|
builder: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
|
if (!classDescriptor.isInline && !classDescriptor.hasInlineClassTypesInSignature()) return
|
||||||
|
|
||||||
|
builder.addVersionRequirement(
|
||||||
|
DescriptorSerializer.writeLanguageVersionRequirement(LanguageFeature.InlineClasses, versionRequirementTable)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ClassDescriptor.hasInlineClassTypesInSignature(): Boolean {
|
||||||
|
for (typeParameter in declaredTypeParameters) {
|
||||||
|
if (typeParameter.upperBounds.any { it.contains(UnwrappedType::isInlineClassType) }) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultType.immediateSupertypes().any { supertype -> supertype.contains(UnwrappedType::isInlineClassType) }) return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
fun propertyProto(descriptor: PropertyDescriptor): ProtoBuf.Property.Builder {
|
fun propertyProto(descriptor: PropertyDescriptor): ProtoBuf.Property.Builder {
|
||||||
val builder = ProtoBuf.Property.newBuilder()
|
val builder = ProtoBuf.Property.newBuilder()
|
||||||
|
|
||||||
@@ -239,6 +265,10 @@ class DescriptorSerializer private constructor(
|
|||||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
|
}
|
||||||
|
|
||||||
extension.serializeProperty(descriptor, builder, versionRequirementTable)
|
extension.serializeProperty(descriptor, builder, versionRequirementTable)
|
||||||
|
|
||||||
return builder
|
return builder
|
||||||
@@ -308,6 +338,10 @@ class DescriptorSerializer private constructor(
|
|||||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
|
}
|
||||||
|
|
||||||
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
|
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
|
||||||
|
|
||||||
extension.serializeFunction(descriptor, builder)
|
extension.serializeFunction(descriptor, builder)
|
||||||
@@ -337,6 +371,10 @@ class DescriptorSerializer private constructor(
|
|||||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (descriptor.hasInlineClassTypesInSignature()) {
|
||||||
|
builder.addVersionRequirement(writeVersionRequirement(LanguageFeature.InlineClasses))
|
||||||
|
}
|
||||||
|
|
||||||
extension.serializeConstructor(descriptor, builder)
|
extension.serializeConstructor(descriptor, builder)
|
||||||
|
|
||||||
return builder
|
return builder
|
||||||
@@ -348,12 +386,20 @@ class DescriptorSerializer private constructor(
|
|||||||
private fun CallableMemberDescriptor.isSuspendOrHasSuspendTypesInSignature(): Boolean {
|
private fun CallableMemberDescriptor.isSuspendOrHasSuspendTypesInSignature(): Boolean {
|
||||||
if (this is FunctionDescriptor && isSuspend) return true
|
if (this is FunctionDescriptor && isSuspend) return true
|
||||||
|
|
||||||
|
return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isSuspendFunctionTypeOrSubtype) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CallableMemberDescriptor.hasInlineClassTypesInSignature(): Boolean {
|
||||||
|
return allTypesFromSignature().any { type -> type.contains(UnwrappedType::isInlineClassType) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CallableMemberDescriptor.allTypesFromSignature(): List<KotlinType> {
|
||||||
return listOfNotNull(
|
return listOfNotNull(
|
||||||
extensionReceiverParameter?.type,
|
extensionReceiverParameter?.type,
|
||||||
returnType,
|
returnType,
|
||||||
*typeParameters.flatMap { it.upperBounds }.toTypedArray(),
|
*typeParameters.flatMap { it.upperBounds }.toTypedArray(),
|
||||||
*valueParameters.map(ValueParameterDescriptor::getType).toTypedArray()
|
*valueParameters.map(ValueParameterDescriptor::getType).toTypedArray()
|
||||||
).any { type -> type.contains(UnwrappedType::isSuspendFunctionTypeOrSubtype) }
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun typeAliasProto(descriptor: TypeAliasDescriptor): ProtoBuf.TypeAlias.Builder {
|
fun typeAliasProto(descriptor: TypeAliasDescriptor): ProtoBuf.TypeAlias.Builder {
|
||||||
@@ -614,15 +660,7 @@ class DescriptorSerializer private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
||||||
val languageVersion = languageFeature.sinceVersion!!
|
return writeLanguageVersionRequirement(languageFeature, versionRequirementTable)
|
||||||
return writeVersionRequirement(
|
|
||||||
languageVersion.major, languageVersion.minor, 0,
|
|
||||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeVersionRequirement(major: Int, minor: Int, patch: Int, versionKind: ProtoBuf.VersionRequirement.VersionKind): Int {
|
|
||||||
return writeVersionRequirement(major, minor, patch, versionKind, versionRequirementTable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of indices into versionRequirementTable, or empty list if there's no @RequireKotlin on the descriptor
|
// Returns a list of indices into versionRequirementTable, or empty list if there's no @RequireKotlin on the descriptor
|
||||||
@@ -758,6 +796,18 @@ class DescriptorSerializer private constructor(
|
|||||||
Collections.sort(this, MemberComparator.INSTANCE)
|
Collections.sort(this, MemberComparator.INSTANCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun writeLanguageVersionRequirement(
|
||||||
|
languageFeature: LanguageFeature,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
): Int {
|
||||||
|
val languageVersion = languageFeature.sinceVersion!!
|
||||||
|
return writeVersionRequirement(
|
||||||
|
languageVersion.major, languageVersion.minor, 0,
|
||||||
|
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION,
|
||||||
|
versionRequirementTable
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun writeVersionRequirement(
|
fun writeVersionRequirement(
|
||||||
major: Int,
|
major: Int,
|
||||||
minor: Int,
|
minor: Int,
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED_FEATURE")
|
||||||
|
inline class IC(val x: String)
|
||||||
|
|
||||||
|
typealias ICAlias = IC
|
||||||
|
|
||||||
|
class Ctor(ic: IC)
|
||||||
|
|
||||||
|
fun simpleFun(f: IC) {}
|
||||||
|
fun aliasedFun(f: ICAlias) {}
|
||||||
|
|
||||||
|
val simpleProp: IC = IC("")
|
||||||
|
|
||||||
|
fun result(r: List<Result<Any>?>) {}
|
||||||
|
|
||||||
|
abstract class Foo : List<IC>
|
||||||
|
interface Bar<T : IC>
|
||||||
@@ -171,4 +171,21 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testInlineClassesAndRelevantDeclarations() {
|
||||||
|
doTest(
|
||||||
|
VersionRequirement.Version(1, 3), DeprecationLevel.ERROR, null, ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION, null,
|
||||||
|
customLanguageVersion = LanguageVersion.KOTLIN_1_2,
|
||||||
|
fqNames = listOf(
|
||||||
|
"test.IC",
|
||||||
|
"test.Ctor.<init>",
|
||||||
|
"test.simpleFun",
|
||||||
|
"test.aliasedFun",
|
||||||
|
"test.simpleProp",
|
||||||
|
"test.result",
|
||||||
|
"test.Foo",
|
||||||
|
"test.Bar"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user