Prohibit @JvmField on properties of inline class types
#KT-26454 Fixed
This commit is contained in:
+5
-1
@@ -28,9 +28,11 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmFieldAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmFieldAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.jvm.checkers.JvmFieldApplicabilityChecker.Problem.*
|
import org.jetbrains.kotlin.resolve.jvm.checkers.JvmFieldApplicabilityChecker.Problem.*
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
|
||||||
@@ -46,7 +48,8 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
|||||||
INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"),
|
INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"),
|
||||||
NOT_PUBLIC_VAL_WITH_JVMFIELD("JvmField could be applied only if all interface companion properties are 'public final val' with '@JvmField' annotation"),
|
NOT_PUBLIC_VAL_WITH_JVMFIELD("JvmField could be applied only if all interface companion properties are 'public final val' with '@JvmField' annotation"),
|
||||||
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"),
|
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"),
|
||||||
DELEGATE("JvmField cannot be applied to delegated property")
|
DELEGATE("JvmField cannot be applied to delegated property"),
|
||||||
|
RETURN_TYPE_IS_INLINE_CLASS("JvmField cannot be applied to a property of an inline class type")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
@@ -75,6 +78,7 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
|||||||
}
|
}
|
||||||
DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() ->
|
DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() ->
|
||||||
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE
|
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE
|
||||||
|
descriptor.returnType?.isInlineClassThatRequiresMangling() == true -> RETURN_TYPE_IS_INLINE_CLASS
|
||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+14
-1
@@ -1,4 +1,4 @@
|
|||||||
// !LANGUAGE: +NestedClassesInAnnotations
|
// !LANGUAGE: +NestedClassesInAnnotations +InlineClasses
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
<!WRONG_ANNOTATION_TARGET!>@kotlin.jvm.JvmField<!>
|
<!WRONG_ANNOTATION_TARGET!>@kotlin.jvm.JvmField<!>
|
||||||
@@ -128,3 +128,16 @@ object O {
|
|||||||
|
|
||||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
private val private = 3
|
private val private = 3
|
||||||
|
|
||||||
|
inline class Foo(val x: Int)
|
||||||
|
|
||||||
|
object IObject {
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
val c: Foo = Foo(42)
|
||||||
|
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
val u = <!EXPERIMENTAL_UNSIGNED_LITERALS!>42u<!>
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
internal val r: Result<Int> = TODO()
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+18
@@ -33,6 +33,14 @@ public final annotation class DemoAnnotation : kotlin.Annotation {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final inline class Foo {
|
||||||
|
public constructor Foo(/*0*/ x: kotlin.Int)
|
||||||
|
public final val x: 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 final class G {
|
public final class G {
|
||||||
public constructor G()
|
public constructor G()
|
||||||
@field:kotlin.jvm.JvmField public final lateinit var lateInit: kotlin.String
|
@field:kotlin.jvm.JvmField public final lateinit var lateInit: kotlin.String
|
||||||
@@ -65,6 +73,16 @@ public interface I {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object IObject {
|
||||||
|
private constructor IObject()
|
||||||
|
@field:kotlin.jvm.JvmField public final val c: Foo
|
||||||
|
@field:kotlin.jvm.JvmField internal final val r: kotlin.Result<kotlin.Int>
|
||||||
|
@field:kotlin.jvm.JvmField public final val u: kotlin.UInt = 42.toUInt()
|
||||||
|
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 K {
|
public interface K {
|
||||||
public abstract val i: kotlin.Int
|
public abstract val i: kotlin.Int
|
||||||
public abstract val j: kotlin.Int
|
public abstract val j: kotlin.Int
|
||||||
|
|||||||
+3
-3
@@ -33,12 +33,12 @@ fun requiresFunctionNameMangling(valueParameterTypes: List<KotlinType>): Boolean
|
|||||||
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
||||||
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
||||||
|
|
||||||
|
fun KotlinType.isInlineClassThatRequiresMangling() =
|
||||||
|
constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true
|
||||||
|
|
||||||
private fun KotlinType.requiresFunctionNameMangling() =
|
private fun KotlinType.requiresFunctionNameMangling() =
|
||||||
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
||||||
|
|
||||||
private fun KotlinType.isInlineClassThatRequiresMangling() =
|
|
||||||
constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true
|
|
||||||
|
|
||||||
private fun isDontMangleClass(classDescriptor: ClassDescriptor) =
|
private fun isDontMangleClass(classDescriptor: ClassDescriptor) =
|
||||||
classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME
|
classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user