Determine underlying property of inline class by its name
Previous way to distinguish "primary constructor properties" from other properties wasn't correct for deserialized properties, because currently we don't have special information about this in metadata
This commit is contained in:
@@ -1707,11 +1707,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
|
|
||||||
boolean isUnderlyingPropertyOfInlineClass =
|
if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(propertyDescriptor)) {
|
||||||
InlineClassesUtilsKt.isInlineClass(propertyDescriptor.getContainingDeclaration()) &&
|
|
||||||
JvmCodegenUtil.hasBackingField(propertyDescriptor, contextKind(), bindingContext);
|
|
||||||
|
|
||||||
if (isUnderlyingPropertyOfInlineClass) {
|
|
||||||
KotlinType propertyType = propertyDescriptor.getType();
|
KotlinType propertyType = propertyDescriptor.getType();
|
||||||
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(propertyType), propertyType, receiver);
|
return StackValue.underlyingValueOfInlineClass(typeMapper.mapType(propertyType), propertyType, receiver);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy
|
|||||||
import org.jetbrains.kotlin.codegen.coroutines.SuspendInlineFunctionGenerationStrategy;
|
import org.jetbrains.kotlin.codegen.coroutines.SuspendInlineFunctionGenerationStrategy;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
|
|
||||||
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||||
import org.jetbrains.kotlin.config.JvmTarget;
|
import org.jetbrains.kotlin.config.JvmTarget;
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
@@ -295,8 +294,7 @@ public class FunctionCodegen {
|
|||||||
// descriptor corresponds to the underlying value
|
// descriptor corresponds to the underlying value
|
||||||
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
|
||||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty();
|
PropertyDescriptor property = ((PropertyAccessorDescriptor) functionDescriptor).getCorrespondingProperty();
|
||||||
// property for the underlying value
|
if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(property)) {
|
||||||
if (JvmCodegenUtil.hasBackingField(property, contextKind, bindingContext)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -135,7 +135,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
|||||||
if (compatibility.allStrongIncompatibilities()) return
|
if (compatibility.allStrongIncompatibilities()) return
|
||||||
|
|
||||||
if (Compatible in compatibility) {
|
if (Compatible in compatibility) {
|
||||||
if (checkActual && requireActualModifier(descriptor, trace)) {
|
if (checkActual && requireActualModifier(descriptor)) {
|
||||||
trace.report(Errors.ACTUAL_MISSING.on(reportOn))
|
trace.report(Errors.ACTUAL_MISSING.on(reportOn))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,16 +204,14 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
|||||||
// - annotation constructors, because annotation classes can only have one constructor
|
// - annotation constructors, because annotation classes can only have one constructor
|
||||||
// - inline class primary constructors, because inline class must have primary constructor
|
// - inline class primary constructors, because inline class must have primary constructor
|
||||||
// - value parameter inside primary constructor of inline class, because inline class must have one value parameter
|
// - value parameter inside primary constructor of inline class, because inline class must have one value parameter
|
||||||
private fun requireActualModifier(descriptor: MemberDescriptor, trace: BindingTrace): Boolean {
|
private fun requireActualModifier(descriptor: MemberDescriptor): Boolean {
|
||||||
return !descriptor.isAnnotationConstructor() &&
|
return !descriptor.isAnnotationConstructor() &&
|
||||||
!descriptor.isPrimaryConstructorOfInlineClass() &&
|
!descriptor.isPrimaryConstructorOfInlineClass() &&
|
||||||
!isMainPropertyOfInlineClass(descriptor, trace)
|
!isUnderlyingPropertyOfInlineClass(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isMainPropertyOfInlineClass(descriptor: MemberDescriptor, trace: BindingTrace): Boolean {
|
private fun isUnderlyingPropertyOfInlineClass(descriptor: MemberDescriptor): Boolean {
|
||||||
if (descriptor !is PropertyDescriptor) return false
|
return descriptor is PropertyDescriptor && descriptor.isUnderlyingPropertyOfInlineClass()
|
||||||
if (!descriptor.containingDeclaration.isInlineClass()) return false
|
|
||||||
return trace.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor] == true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source.
|
// This should ideally be handled by CallableMemberDescriptor.Kind, but default constructors have kind DECLARATION and non-empty source.
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// FILE: A.kt
|
||||||
|
|
||||||
|
package a
|
||||||
|
|
||||||
|
@Suppress("UNSUPPORTED_FEATURE")
|
||||||
|
inline class Foo(val x: IntArray) {
|
||||||
|
val size: Int get() = x.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: B.kt
|
||||||
|
|
||||||
|
import a.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = Foo(intArrayOf(3, 4))
|
||||||
|
if (a.size != 2) return "Fail"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -39,6 +39,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/annotationsOnTypeAliases.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("callDeserializedPropertyOnInlineClassType.kt")
|
||||||
|
public void testCallDeserializedPropertyOnInlineClassType() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/callDeserializedPropertyOnInlineClassType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("callsToMultifileClassFromOtherPackage.kt")
|
@TestMetadata("callsToMultifileClassFromOtherPackage.kt")
|
||||||
public void testCallsToMultifileClassFromOtherPackage() throws Exception {
|
public void testCallsToMultifileClassFromOtherPackage() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/callsToMultifileClassFromOtherPackage.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/callsToMultifileClassFromOtherPackage.kt");
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -39,3 +40,10 @@ fun KotlinType.isNullableUnderlyingType(): Boolean {
|
|||||||
|
|
||||||
return TypeUtils.isNullableType(underlyingType)
|
return TypeUtils.isNullableType(underlyingType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PropertyDescriptor.isUnderlyingPropertyOfInlineClass(): Boolean {
|
||||||
|
val containingDeclaration = this.containingDeclaration
|
||||||
|
if (!containingDeclaration.isInlineClass()) return false
|
||||||
|
|
||||||
|
return (containingDeclaration as ClassDescriptor).underlyingRepresentation()?.name == this.name
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user