[FIX, Frontend] Fix recursive check for multi-field value classes
This commit is contained in:
committed by
Space
parent
e69a973b07
commit
c7edc353d3
+5
-10
@@ -221,20 +221,15 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
isRecursiveInlineClassType(hashSetOf(), session)
|
||||
|
||||
private fun ConeKotlinType.isRecursiveInlineClassType(visited: HashSet<ConeKotlinType>, session: FirSession): Boolean {
|
||||
if (!visited.add(this)) return true
|
||||
|
||||
val asRegularClass = this.toRegularClassSymbol(session) ?: return false
|
||||
|
||||
if (!asRegularClass.isInlineOrValueClass()) return false
|
||||
val asRegularClass = this.toRegularClassSymbol(session)?.takeIf { it.isInlineOrValueClass() } ?: return false
|
||||
val primaryConstructor = asRegularClass.declarationSymbols
|
||||
.firstOrNull { it is FirConstructorSymbol && it.isPrimary } as FirConstructorSymbol?
|
||||
?: return false
|
||||
return primaryConstructor
|
||||
.valueParameterSymbols
|
||||
.firstOrNull()
|
||||
?.resolvedReturnTypeRef
|
||||
?.coneType
|
||||
?.isRecursiveInlineClassType(visited, session) == true
|
||||
|
||||
return !visited.add(this) || primaryConstructor.valueParameterSymbols.any {
|
||||
it.resolvedReturnTypeRef.coneType.isRecursiveInlineClassType(visited, session)
|
||||
}.also { visited.remove(this) }
|
||||
}
|
||||
|
||||
private fun FirRegularClass.isSubtypeOfCloneable(session: FirSession): Boolean {
|
||||
|
||||
@@ -270,7 +270,7 @@ class DeclarationsChecker(
|
||||
|
||||
if (declaration is KtPrimaryConstructor &&
|
||||
!DescriptorUtils.isAnnotationClass(constructorDescriptor.constructedClass) &&
|
||||
!constructorDescriptor.constructedClass.isInlineClass()
|
||||
!constructorDescriptor.constructedClass.isInlineOrValueClass()
|
||||
) {
|
||||
for (parameter in declaration.valueParameters) {
|
||||
if (parameter.hasValOrVar()) {
|
||||
|
||||
+8
-10
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.contracts.parsing.isEqualsDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -16,12 +15,10 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.modalityModifier
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
@@ -80,7 +77,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
return
|
||||
}
|
||||
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses) && descriptor.isValueClass()) {
|
||||
if (primaryConstructor.valueParameters.isEmpty()) {
|
||||
(primaryConstructor.valueParameterList ?: declaration).let {
|
||||
trace.report(Errors.VALUE_CLASS_EMPTY_CONSTRUCTOR.on(it))
|
||||
@@ -95,7 +92,9 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
var baseParametersOk = true
|
||||
for (baseParameter in primaryConstructor.valueParameters) {
|
||||
val baseParameterTypes = descriptor.safeAs<ClassDescriptor>()?.defaultType?.substitutedUnderlyingTypes() ?: emptyList()
|
||||
|
||||
for ((baseParameter, baseParameterType) in primaryConstructor.valueParameters zip baseParameterTypes) {
|
||||
|
||||
if (!isParameterAcceptableForInlineClass(baseParameter)) {
|
||||
trace.report(Errors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.on(baseParameter))
|
||||
@@ -103,7 +102,6 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
continue
|
||||
}
|
||||
|
||||
val baseParameterType = descriptor.safeAs<ClassDescriptor>()?.defaultType?.substitutedUnderlyingType()
|
||||
val baseParameterTypeReference = baseParameter.typeReference
|
||||
if (baseParameterType != null && baseParameterTypeReference != null) {
|
||||
if (baseParameterType.isInapplicableParameterType()) {
|
||||
@@ -112,7 +110,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
continue
|
||||
}
|
||||
|
||||
if (baseParameterType.isRecursiveInlineClassType()) { // todo check work for MF VC
|
||||
if (baseParameterType.isRecursiveInlineOrValueClassType()) {
|
||||
trace.report(Errors.VALUE_CLASS_CANNOT_BE_RECURSIVE.on(baseParameterTypeReference))
|
||||
baseParametersOk = false
|
||||
continue
|
||||
@@ -176,7 +174,7 @@ class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker {
|
||||
if (declaration !is KtProperty) return
|
||||
if (descriptor !is PropertyDescriptor) return
|
||||
|
||||
if (!descriptor.containingDeclaration.isInlineClass()) return
|
||||
if (!descriptor.containingDeclaration.isInlineOrValueClass()) return
|
||||
|
||||
if (context.trace.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) == true) {
|
||||
context.trace.report(Errors.PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS.on(declaration))
|
||||
@@ -194,7 +192,7 @@ class InnerClassInsideInlineClass : DeclarationChecker {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
if (!descriptor.isInner) return
|
||||
|
||||
if (!descriptor.containingDeclaration.isInlineClass()) return
|
||||
if (!descriptor.containingDeclaration.isInlineOrValueClass()) return
|
||||
|
||||
context.trace.report(Errors.INNER_CLASS_INSIDE_VALUE_CLASS.on(declaration.modifierList!!.getModifier(KtTokens.INNER_KEYWORD)!!))
|
||||
}
|
||||
@@ -208,7 +206,7 @@ class ReservedMembersAndConstructsForInlineClass : DeclarationChecker {
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val containingDeclaration = descriptor.containingDeclaration ?: return
|
||||
if (!containingDeclaration.isInlineClass()) return
|
||||
if (!containingDeclaration.isInlineOrValueClass()) return
|
||||
|
||||
if (descriptor !is FunctionDescriptor) return
|
||||
|
||||
|
||||
+29
-5
@@ -23,6 +23,8 @@ value class F6(val x: String)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class A(
|
||||
val f1: F1,
|
||||
val f2: F2,
|
||||
val f3: F3,
|
||||
val f4: F4,
|
||||
val f5: F5,
|
||||
@@ -46,7 +48,7 @@ fun box(): String {
|
||||
val f4 = F4(5)
|
||||
val f5 = F5(UInt.MAX_VALUE.dec())
|
||||
val f6 = F6("678")
|
||||
val a1 = A(f3, f4, f5, f6, 9, UInt.MAX_VALUE - 2U, "0")
|
||||
val a1 = A(f1, f2, f3, f4, f5, f6, 9, UInt.MAX_VALUE - 2U, "0")
|
||||
val a2 = a1
|
||||
val b = B(a1, a2)
|
||||
|
||||
@@ -60,6 +62,26 @@ fun box(): String {
|
||||
assert(f5.x == UInt.MAX_VALUE - 1U)
|
||||
assert(f6.x == "678")
|
||||
|
||||
assert(f1 == a1.f1)
|
||||
assert(f1.hashCode() == a1.f1.hashCode())
|
||||
assert(f1.toString() == a1.f1.toString())
|
||||
assert(f1 == a2.f1)
|
||||
assert(f1.hashCode() == a2.f1.hashCode())
|
||||
assert(f1.toString() == a2.f1.toString())
|
||||
assert(a1.f1 == a2.f1)
|
||||
assert(a1.f1.hashCode() == a2.f1.hashCode())
|
||||
assert(a1.f1.toString() == a2.f1.toString())
|
||||
|
||||
assert(f2 == a1.f2)
|
||||
assert(f2.hashCode() == a1.f2.hashCode())
|
||||
assert(f2.toString() == a1.f2.toString())
|
||||
assert(f2 == a2.f2)
|
||||
assert(f2.hashCode() == a2.f2.hashCode())
|
||||
assert(f2.toString() == a2.f2.toString())
|
||||
assert(a1.f2 == a2.f2)
|
||||
assert(a1.f2.hashCode() == a2.f2.hashCode())
|
||||
assert(a1.f2.toString() == a2.f2.toString())
|
||||
|
||||
assert(f1 == a1.f3.x)
|
||||
assert(f1.hashCode() == a1.f3.x.hashCode())
|
||||
assert(f1.toString() == a1.f3.x.toString())
|
||||
@@ -159,15 +181,17 @@ fun box(): String {
|
||||
assert(b.toString() == b.toString())
|
||||
assert(b.hashCode() == b.hashCode())
|
||||
|
||||
fun String.assertGoodBasicToString(expected: String) = assert(matches(Regex("^([_a-zA-Z]+[.])*$expected@[0-9a-f]+$"))) { this }
|
||||
|
||||
assert(f1.toString() == "F1(x=1)") { f1.toString() }
|
||||
assert(f2.toString() == "F2(x=4294967295)") { f2.toString() }
|
||||
assert(f3.toString().startsWith("F3@")) { f3.toString() } // not data class yet
|
||||
f3.toString().assertGoodBasicToString("F3") // not data class yet
|
||||
assert(f4.toString() == "F4(x=5)") { f4.toString() }
|
||||
assert(f5.toString() == "F5(x=4294967294)") { f5.toString() }
|
||||
assert(f6.toString() == "F6(x=678)") { f6.toString() }
|
||||
assert(a1.toString().startsWith("A@")) { a1.toString() } // not data class yet
|
||||
assert(a2.toString().startsWith("A@")) { a2.toString() } // not data class yet
|
||||
assert(b.toString().let { it.startsWith("OverridenBToString(a1 = A@") && ", a2 = A@" in it }) { b.toString() } // not data class yet
|
||||
a1.toString().assertGoodBasicToString("A") // not data class yet
|
||||
a2.toString().assertGoodBasicToString("A") // not data class yet
|
||||
assert(b.toString() == "OverridenBToString(a1 = $a1, a2 = $a2)") { b.toString() }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
+30
@@ -38,6 +38,12 @@ value class C4(val x: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>D4?<!>, val y: <!VALUE_
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class D4(val x: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>D4?<!>, val y: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>C4?<!>)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class E4(val x: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>E4?<!>, val y: Int)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class F4(val x: Int, val y: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>F4?<!>)
|
||||
|
||||
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
@@ -66,3 +72,27 @@ value class A8<T : B8<<!UPPER_BOUND_VIOLATED!>T<!>>>(val x: <!VALUE_CLASS_HAS_IN
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class B8<T : A8<<!UPPER_BOUND_VIOLATED!>T<!>>>(val x: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T?<!>, val y: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T?<!>)
|
||||
|
||||
interface I1
|
||||
interface I2
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class A<T, G : C?>(
|
||||
val t1: List<T>,
|
||||
val t2: UInt,
|
||||
val t3: List<G?>,
|
||||
val t4: UInt,
|
||||
val t5: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>C<!>,
|
||||
val t6: Int,
|
||||
val t7: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>B<!>,
|
||||
val t8: String,
|
||||
val t9: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T<!>,
|
||||
val t10: Char,
|
||||
val t11: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>T?<!>,
|
||||
) where T : I1, T : B?, T : I2
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class B(val x: UInt, val a: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>A<B, Nothing><!>) : I1, I2
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class C(val x: UInt, val a: <!VALUE_CLASS_CANNOT_BE_RECURSIVE!>A<B, Nothing><!>)
|
||||
|
||||
+100
-33
@@ -1,5 +1,23 @@
|
||||
package
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class A</*0*/ T : I1, /*1*/ G : C?> where T : B?, T : I2 {
|
||||
public constructor A</*0*/ T : I1, /*1*/ G : C?>(/*0*/ t1: kotlin.collections.List<T>, /*1*/ t2: kotlin.UInt, /*2*/ t3: kotlin.collections.List<G?>, /*3*/ t4: kotlin.UInt, /*4*/ t5: C, /*5*/ t6: kotlin.Int, /*6*/ t7: B, /*7*/ t8: kotlin.String, /*8*/ t9: T, /*9*/ t10: kotlin.Char, /*10*/ t11: T?) where T : B?, T : I2
|
||||
public final val t1: kotlin.collections.List<T>
|
||||
public final val t10: kotlin.Char
|
||||
public final val t11: T?
|
||||
public final val t2: kotlin.UInt
|
||||
public final val t3: kotlin.collections.List<G?>
|
||||
public final val t4: kotlin.UInt
|
||||
public final val t5: C
|
||||
public final val t6: kotlin.Int
|
||||
public final val t7: B
|
||||
public final val t8: kotlin.String
|
||||
public final val t9: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class A1 {
|
||||
public constructor A1(/*0*/ x: A1)
|
||||
public final val x: A1
|
||||
@@ -28,9 +46,9 @@ package
|
||||
public constructor A4(/*0*/ x: B4, /*1*/ y: B4)
|
||||
public final val x: B4
|
||||
public final val y: B4
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class A5</*0*/ T : A5<T>> {
|
||||
@@ -45,45 +63,54 @@ package
|
||||
public constructor A6</*0*/ T : B6<T>>(/*0*/ x: T, /*1*/ y: T)
|
||||
public final val x: T
|
||||
public final val y: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class A7</*0*/ T : B7<T>> {
|
||||
public constructor A7</*0*/ T : B7<T>>(/*0*/ x: T, /*1*/ y: T)
|
||||
public final val x: T
|
||||
public final val y: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class A8</*0*/ T : B8<T>> {
|
||||
public constructor A8</*0*/ T : B8<T>>(/*0*/ x: T?, /*1*/ y: T?)
|
||||
public final val x: T?
|
||||
public final val y: T?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B : I1, I2 {
|
||||
public constructor B(/*0*/ x: kotlin.UInt, /*1*/ a: A<B, kotlin.Nothing>)
|
||||
public final val a: A<B, kotlin.Nothing>
|
||||
public final val x: kotlin.UInt
|
||||
public open override /*2*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*2*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B1 {
|
||||
public constructor B1(/*0*/ x: B1, /*1*/ y: B1)
|
||||
public final val x: B1
|
||||
public final val y: B1
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B2 {
|
||||
public constructor B2(/*0*/ x: A2, /*1*/ y: A2)
|
||||
public final val x: A2
|
||||
public final val y: A2
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B3 {
|
||||
@@ -98,18 +125,18 @@ package
|
||||
public constructor B4(/*0*/ x: A4, /*1*/ y: A4)
|
||||
public final val x: A4
|
||||
public final val y: A4
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B5</*0*/ T : B5<T>> {
|
||||
public constructor B5</*0*/ T : B5<T>>(/*0*/ x: T, /*1*/ y: T)
|
||||
public final val x: T
|
||||
public final val y: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B6</*0*/ T : A6<T>> {
|
||||
@@ -124,15 +151,24 @@ package
|
||||
public constructor B7</*0*/ T : A7<T>>(/*0*/ x: T, /*1*/ y: T)
|
||||
public final val x: T
|
||||
public final val y: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class B8</*0*/ T : A8<T>> {
|
||||
public constructor B8</*0*/ T : A8<T>>(/*0*/ x: T?, /*1*/ y: T?)
|
||||
public final val x: T?
|
||||
public final val y: T?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class C {
|
||||
public constructor C(/*0*/ x: kotlin.UInt, /*1*/ a: A<B, kotlin.Nothing>)
|
||||
public final val a: A<B, kotlin.Nothing>
|
||||
public final val x: kotlin.UInt
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
@@ -142,16 +178,47 @@ package
|
||||
public constructor C4(/*0*/ x: D4?, /*1*/ y: D4?)
|
||||
public final val x: D4?
|
||||
public final val y: D4?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class D4 {
|
||||
public constructor D4(/*0*/ x: D4?, /*1*/ y: C4?)
|
||||
public final val x: D4?
|
||||
public final val y: C4?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class E4 {
|
||||
public constructor E4(/*0*/ x: E4?, /*1*/ y: kotlin.Int)
|
||||
public final val x: E4?
|
||||
public final val y: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class F4 {
|
||||
public constructor F4(/*0*/ x: kotlin.Int, /*1*/ y: F4?)
|
||||
public final val x: kotlin.Int
|
||||
public final val y: F4?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface I2 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -45,17 +45,17 @@ package kotlin {
|
||||
public constructor A5(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
public final val x: kotlin.Int
|
||||
public final val y: kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline public final value class A6 {
|
||||
public constructor A6(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
public final val y: kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline public final value class A7 {
|
||||
|
||||
Vendored
+6
@@ -39,5 +39,11 @@ value class BarNullable(val u: Unit?, val y: Unit?)
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Baz(val u: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>Nothing<!>, val y: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>Nothing<!>)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Baz1(val u: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>Nothing<!>, val y: Int)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class Baz2(val u: Int, val y: <!VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE!>Nothing<!>)
|
||||
|
||||
OPTIONAL_JVM_INLINE_ANNOTATION
|
||||
value class BazNullable(val u: Nothing?, val y: Nothing?)
|
||||
|
||||
compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.txt
Vendored
+49
-30
@@ -4,36 +4,54 @@ package
|
||||
public constructor Bar(/*0*/ u: kotlin.Unit, /*1*/ y: kotlin.Unit)
|
||||
public final val u: kotlin.Unit
|
||||
public final val y: kotlin.Unit
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class BarNullable {
|
||||
public constructor BarNullable(/*0*/ u: kotlin.Unit?, /*1*/ y: kotlin.Unit?)
|
||||
public final val u: kotlin.Unit?
|
||||
public final val y: kotlin.Unit?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class Baz {
|
||||
public constructor Baz(/*0*/ u: kotlin.Nothing, /*1*/ y: kotlin.Nothing)
|
||||
public final val u: kotlin.Nothing
|
||||
public final val y: kotlin.Nothing
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class Baz1 {
|
||||
public constructor Baz1(/*0*/ u: kotlin.Nothing, /*1*/ y: kotlin.Int)
|
||||
public final val u: kotlin.Nothing
|
||||
public final val y: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class Baz2 {
|
||||
public constructor Baz2(/*0*/ u: kotlin.Int, /*1*/ y: kotlin.Nothing)
|
||||
public final val u: kotlin.Int
|
||||
public final val y: kotlin.Nothing
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class BazNullable {
|
||||
public constructor BazNullable(/*0*/ u: kotlin.Nothing?, /*1*/ y: kotlin.Nothing?)
|
||||
public final val u: kotlin.Nothing?
|
||||
public final val y: kotlin.Nothing?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class Empty</*0*/ T> {
|
||||
@@ -47,52 +65,53 @@ package
|
||||
public constructor Foo</*0*/ T>(/*0*/ x: T, /*1*/ y: T)
|
||||
public final val x: T
|
||||
public final val y: T
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class FooGenericArray</*0*/ T> {
|
||||
public constructor FooGenericArray</*0*/ T>(/*0*/ x: kotlin.Array<T>, /*1*/ y: kotlin.Array<T>)
|
||||
public final val x: kotlin.Array<T>
|
||||
public final val y: kotlin.Array<T>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class FooGenericArray2</*0*/ T> {
|
||||
public constructor FooGenericArray2</*0*/ T>(/*0*/ x: kotlin.Array<kotlin.Array<T>>, /*1*/ y: kotlin.Array<kotlin.Array<T>>)
|
||||
public final val x: kotlin.Array<kotlin.Array<T>>
|
||||
public final val y: kotlin.Array<kotlin.Array<T>>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class FooNullable</*0*/ T> {
|
||||
public constructor FooNullable</*0*/ T>(/*0*/ x: T?, /*1*/ y: T?)
|
||||
public final val x: T?
|
||||
public final val y: T?
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class FooStarProjectedArray {
|
||||
public constructor FooStarProjectedArray(/*0*/ x: kotlin.Array<*>, /*1*/ y: kotlin.Array<*>)
|
||||
public final val x: kotlin.Array<*>
|
||||
public final val y: kotlin.Array<*>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Suppress(names = {"OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE"}) @kotlin.jvm.JvmInline public final value class FooStarProjectedArray2 {
|
||||
public constructor FooStarProjectedArray2(/*0*/ x: kotlin.Array<kotlin.Array<*>>, /*1*/ y: kotlin.Array<kotlin.Array<*>>)
|
||||
public final val x: kotlin.Array<kotlin.Array<*>>
|
||||
public final val y: kotlin.Array<kotlin.Array<*>>
|
||||
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
@@ -19,34 +19,51 @@ val JVM_INLINE_ANNOTATION_CLASS_ID = ClassId.topLevel(JVM_INLINE_ANNOTATION_FQ_N
|
||||
|
||||
// FIXME: DeserializedClassDescriptor in reflection do not have @JvmInline annotation, that we
|
||||
// FIXME: would like to check as well.
|
||||
fun DeclarationDescriptor.isInlineClass(): Boolean =
|
||||
this is ClassDescriptor && (isInline || isValue) && unsubstitutedPrimaryConstructor?.valueParameters?.size == 1
|
||||
fun DeclarationDescriptor.isInlineClass(): Boolean = when {
|
||||
this !is ClassDescriptor -> false
|
||||
isInline -> true
|
||||
else -> isValue && (unsubstitutedPrimaryConstructor?.valueParameters?.size?.let { it == 1 } ?: true)
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.isValueClass(): Boolean =
|
||||
this is ClassDescriptor && isValue
|
||||
|
||||
fun DeclarationDescriptor.isInlineOrValueClass(): Boolean = isInlineClass() || isValueClass()
|
||||
|
||||
fun KotlinType.unsubstitutedUnderlyingType(): KotlinType? =
|
||||
constructor.declarationDescriptor.safeAs<ClassDescriptor>()?.inlineClassRepresentation?.underlyingType
|
||||
|
||||
fun KotlinType.unsubstitutedUnderlyingTypes(): List<KotlinType> {
|
||||
val declarationDescriptor = constructor.declarationDescriptor.safeAs<ClassDescriptor>() ?: return emptyList()
|
||||
return when {
|
||||
declarationDescriptor.isInlineClass() -> listOfNotNull(unsubstitutedUnderlyingType())
|
||||
declarationDescriptor.isValueClass() ->
|
||||
declarationDescriptor.unsubstitutedPrimaryConstructor?.valueParameters?.map { it.type } ?: emptyList()
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun KotlinType.isInlineClassType(): Boolean = constructor.declarationDescriptor?.isInlineClass() ?: false
|
||||
|
||||
fun KotlinType.substitutedUnderlyingType(): KotlinType? =
|
||||
unsubstitutedUnderlyingType()?.let { TypeSubstitutor.create(this).substitute(it, Variance.INVARIANT) }
|
||||
|
||||
fun KotlinType.isRecursiveInlineClassType(): Boolean =
|
||||
isRecursiveInlineClassTypeInner(hashSetOf())
|
||||
fun KotlinType.substitutedUnderlyingTypes(): List<KotlinType?> =
|
||||
unsubstitutedUnderlyingTypes().map { TypeSubstitutor.create(this).substitute(it, Variance.INVARIANT) }
|
||||
|
||||
private fun KotlinType.isRecursiveInlineClassTypeInner(visited: HashSet<ClassifierDescriptor>): Boolean {
|
||||
val descriptor = constructor.declarationDescriptor?.original ?: return false
|
||||
fun KotlinType.isRecursiveInlineOrValueClassType(): Boolean =
|
||||
isRecursiveInlineOrValueClassTypeInner(hashSetOf())
|
||||
|
||||
if (!visited.add(descriptor)) return true
|
||||
|
||||
return when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
descriptor.isInlineClass() &&
|
||||
unsubstitutedUnderlyingType()?.isRecursiveInlineClassTypeInner(visited) == true
|
||||
|
||||
is TypeParameterDescriptor ->
|
||||
descriptor.upperBounds.any { it.isRecursiveInlineClassTypeInner(visited) }
|
||||
|
||||
else -> false
|
||||
private fun KotlinType.isRecursiveInlineOrValueClassTypeInner(visited: HashSet<ClassifierDescriptor>): Boolean {
|
||||
val types = when (val descriptor = constructor.declarationDescriptor?.original?.takeIf { it.isInlineOrValueClass() }) {
|
||||
is ClassDescriptor -> if (descriptor.isInlineOrValueClass()) unsubstitutedUnderlyingTypes() else emptyList()
|
||||
is TypeParameterDescriptor -> descriptor.upperBounds
|
||||
else -> emptyList()
|
||||
}
|
||||
return types.any {
|
||||
val classifier = it.constructor.declarationDescriptor?.original ?: return@any false
|
||||
!visited.add(classifier) || it.isRecursiveInlineOrValueClassTypeInner(visited).also { visited.remove(classifier) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user