[Commonizer] Commonize 'val' and 'var' properties
If a setter is not present on all platforms a fallback private setter shall be emitted. ^KT-47502 Verification Pending ^KT-47691 Verification Pending
This commit is contained in:
committed by
Space
parent
c4d90dc744
commit
8bab6c3076
@@ -34,4 +34,30 @@ open class AssociativeCommonizerAdapter<T : Any>(
|
|||||||
_result = commonizer.commonize(currentResult, next)
|
_result = commonizer.commonize(currentResult, next)
|
||||||
return _result != null
|
return _result != null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> AssociativeCommonizer<T?>.asNullableCommonizer(): Commonizer<T?, T?> = NullableAssociativeCommonizerAdapter(this)
|
||||||
|
|
||||||
|
open class NullableAssociativeCommonizerAdapter<T>(
|
||||||
|
private val commonizer: AssociativeCommonizer<T?>
|
||||||
|
) : Commonizer<T?, T?> {
|
||||||
|
|
||||||
|
private var isInitialized = false
|
||||||
|
private var _result: T? = null
|
||||||
|
|
||||||
|
override val result: T?
|
||||||
|
get() = _result
|
||||||
|
|
||||||
|
override fun commonizeWith(next: T?): Boolean {
|
||||||
|
val currentResult = _result
|
||||||
|
|
||||||
|
if (!isInitialized) {
|
||||||
|
_result = next
|
||||||
|
isInitialized = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
_result = commonizer.commonize(currentResult, next)
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,14 +10,19 @@ import org.jetbrains.kotlin.commonizer.cir.CirProperty
|
|||||||
import org.jetbrains.kotlin.commonizer.cir.CirPropertyGetter
|
import org.jetbrains.kotlin.commonizer.cir.CirPropertyGetter
|
||||||
import org.jetbrains.kotlin.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
|
import org.jetbrains.kotlin.commonizer.core.PropertyCommonizer.ConstCommonizationState.*
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
|
||||||
class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirProperty>(classifiers) {
|
class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer<CirProperty>(classifiers) {
|
||||||
private val setter = PropertySetterCommonizer()
|
private val setter = PropertySetterCommonizer.asNullableCommonizer()
|
||||||
private var isExternal = true
|
private var isExternal = true
|
||||||
private lateinit var constCommonizationState: ConstCommonizationState
|
private lateinit var constCommonizationState: ConstCommonizationState
|
||||||
|
|
||||||
override fun commonizationResult(): CirProperty {
|
override fun commonizationResult(): CirProperty {
|
||||||
val setter = setter.result
|
val modality = modality.result
|
||||||
|
|
||||||
|
val setter = setter.result?.takeIf { setter ->
|
||||||
|
setter !== PropertySetterCommonizer.privateFallbackSetter || modality == Modality.FINAL
|
||||||
|
}
|
||||||
|
|
||||||
val constCommonizationState = constCommonizationState
|
val constCommonizationState = constCommonizationState
|
||||||
val constCompileTimeInitializer = (constCommonizationState as? ConstSameValue)?.compileTimeInitializer
|
val constCompileTimeInitializer = (constCommonizationState as? ConstSameValue)?.compileTimeInitializer
|
||||||
@@ -27,7 +32,7 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP
|
|||||||
name = name,
|
name = name,
|
||||||
typeParameters = typeParameters.result,
|
typeParameters = typeParameters.result,
|
||||||
visibility = visibility.result,
|
visibility = visibility.result,
|
||||||
modality = modality.result,
|
modality = modality,
|
||||||
containingClass = null, // does not matter
|
containingClass = null, // does not matter
|
||||||
isExternal = isExternal,
|
isExternal = isExternal,
|
||||||
extensionReceiver = extensionReceiver.result,
|
extensionReceiver = extensionReceiver.result,
|
||||||
|
|||||||
+20
-7
@@ -5,12 +5,25 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.commonizer.core
|
package org.jetbrains.kotlin.commonizer.core
|
||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirHasVisibility
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirPropertySetter
|
import org.jetbrains.kotlin.commonizer.cir.CirPropertySetter
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
|
||||||
class PropertySetterCommonizer : AbstractNullableCommonizer<CirPropertySetter, CirPropertySetter, CirHasVisibility, Visibility>(
|
object PropertySetterCommonizer : AssociativeCommonizer<CirPropertySetter?> {
|
||||||
wrappedCommonizerFactory = { VisibilityCommonizer.equalizing() },
|
override fun commonize(first: CirPropertySetter?, second: CirPropertySetter?): CirPropertySetter? {
|
||||||
extractor = { it },
|
if (first == null && second == null) return null
|
||||||
builder = CirPropertySetter::createDefaultNoAnnotations
|
if (first != null && second == null) return privateFallbackSetter
|
||||||
)
|
if (first == null && second != null) return privateFallbackSetter
|
||||||
|
|
||||||
|
if (first != null && second != null) {
|
||||||
|
if (Visibilities.compare(first.visibility, second.visibility) == 0) {
|
||||||
|
return CirPropertySetter.createDefaultNoAnnotations(first.visibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateFallbackSetter
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val privateFallbackSetter = CirPropertySetter.createDefaultNoAnnotations(Visibilities.Private)
|
||||||
|
}
|
||||||
+9
-1
@@ -9,8 +9,16 @@ expect var setterWithDelegation1: Int
|
|||||||
expect var setterWithDelegation2: Int
|
expect var setterWithDelegation2: Int
|
||||||
|
|
||||||
expect var defaultSetteCustomVisibility1: Int
|
expect var defaultSetteCustomVisibility1: Int
|
||||||
|
expect var defaultSetteCustomVisibility2: Int
|
||||||
|
private set
|
||||||
expect var defaultSetteCustomVisibility3 = 42
|
expect var defaultSetteCustomVisibility3 = 42
|
||||||
internal set
|
internal set
|
||||||
|
expect var defaultSetteCustomVisibility4: Int
|
||||||
|
private set
|
||||||
|
expect var defaultSetteCustomVisibility5: Int
|
||||||
|
private set
|
||||||
|
|
||||||
expect val propertyWithoutSetter: Int
|
expect val propertyWithoutSetter: Int
|
||||||
expect var propertyWithSetter: Int
|
expect var propertyMaybeSetter: Int
|
||||||
|
private set
|
||||||
|
expect var propertyWithSetter: Int
|
||||||
+48
-89
@@ -6,101 +6,60 @@
|
|||||||
package org.jetbrains.kotlin.commonizer.core
|
package org.jetbrains.kotlin.commonizer.core
|
||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.cir.CirPropertySetter
|
import org.jetbrains.kotlin.commonizer.cir.CirPropertySetter
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.Internal
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.Local
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.Private
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.Protected
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.Public
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
import kotlin.test.assertSame
|
||||||
|
|
||||||
class PropertySetterCommonizerTest : AbstractCommonizerTest<CirPropertySetter?, CirPropertySetter?>() {
|
class PropertySetterCommonizerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun missingOnly() = super.doTestSuccess(
|
fun `missing only`() {
|
||||||
expected = null,
|
assertNull(
|
||||||
null, null, null
|
PropertySetterCommonizer.commonize(null, null),
|
||||||
)
|
"Expected no property setting being commonized from nulls"
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun missingAndPublic() = doTestFailure(
|
|
||||||
null, null, null, Public
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun publicAndMissing() = doTestFailure(
|
|
||||||
Public, Public, Public, null
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun protectedAndMissing() = doTestFailure(
|
|
||||||
Protected, Protected, null
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun missingAndInternal() = doTestFailure(
|
|
||||||
null, null, Internal
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun publicOnly() = doTestSuccess(
|
|
||||||
expected = Public,
|
|
||||||
Public, Public, Public
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun protectedOnly() = doTestSuccess(
|
|
||||||
expected = Protected,
|
|
||||||
Protected, Protected, Protected
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun internalOnly() = doTestSuccess(
|
|
||||||
expected = Internal,
|
|
||||||
Internal, Internal, Internal
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun privateOnly() = doTestFailure(
|
|
||||||
Private
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun publicAndProtected() = doTestFailure(
|
|
||||||
Public, Public, Protected
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun publicAndInternal() = doTestFailure(
|
|
||||||
Public, Public, Internal
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun protectedAndInternal() = doTestFailure(
|
|
||||||
Protected, Protected, Internal
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun publicAndPrivate() = doTestFailure(
|
|
||||||
Public, Public, Private
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test(expected = IllegalCommonizerStateException::class)
|
|
||||||
fun somethingUnexpected() = doTestFailure(
|
|
||||||
Public, Local
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun doTestSuccess(expected: Visibility?, vararg variants: Visibility?) =
|
|
||||||
super.doTestSuccess(
|
|
||||||
expected = expected?.let { CirPropertySetter.createDefaultNoAnnotations(expected) },
|
|
||||||
*variants.map { it?.let(CirPropertySetter::createDefaultNoAnnotations) }.toTypedArray()
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun doTestFailure(vararg variants: Visibility?) =
|
@Test
|
||||||
super.doTestFailure(
|
fun `missing and public`() {
|
||||||
*variants.map { it?.let(CirPropertySetter::createDefaultNoAnnotations) }.toTypedArray(),
|
assertSame(
|
||||||
shouldFailOnFirstVariant = false
|
PropertySetterCommonizer.privateFallbackSetter,
|
||||||
|
PropertySetterCommonizer.commonize(null, CirPropertySetter.createDefaultNoAnnotations(Visibilities.Public))
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createCommonizer() = PropertySetterCommonizer()
|
@Test
|
||||||
|
fun `public public`() {
|
||||||
|
assertEquals(
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Public),
|
||||||
|
PropertySetterCommonizer.commonize(
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Public),
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Public)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `internal internal`() {
|
||||||
|
assertEquals(
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Internal),
|
||||||
|
PropertySetterCommonizer.commonize(
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Internal),
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Internal)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `internal public`() {
|
||||||
|
assertEquals(
|
||||||
|
PropertySetterCommonizer.privateFallbackSetter,
|
||||||
|
PropertySetterCommonizer.commonize(
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Internal),
|
||||||
|
CirPropertySetter.createDefaultNoAnnotations(Visibilities.Public)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user