Prohibit @JvmName on functions that are assumed to be mangled
#KT-26454 In Progress
This commit is contained in:
+7
@@ -34,11 +34,14 @@ import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithCorres
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling
|
||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameMangling
|
||||
|
||||
class LocalFunInlineChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
@@ -143,6 +146,10 @@ class JvmNameAnnotationChecker : DeclarationChecker {
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
if (DescriptorUtils.isOverride(descriptor) || descriptor.isOverridable) {
|
||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||
} else if (descriptor.containingDeclaration.isInlineClassThatRequiresMangling() ||
|
||||
requiresFunctionNameMangling(descriptor.valueParameters.map { it.type })
|
||||
) {
|
||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
inline class Foo(val x: Int) {
|
||||
<!INAPPLICABLE_JVM_NAME!>@JvmName("other")<!>
|
||||
fun simple() {}
|
||||
}
|
||||
|
||||
<!INAPPLICABLE_JVM_NAME!>@JvmName("bad")<!>
|
||||
fun bar(f: Foo) {}
|
||||
|
||||
@JvmName("good")
|
||||
fun baz(r: Result<Int>) {}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
@kotlin.jvm.JvmName(name = "bad") public fun bar(/*0*/ f: Foo): kotlin.Unit
|
||||
@kotlin.jvm.JvmName(name = "good") public fun baz(/*0*/ r: kotlin.Result<kotlin.Int>): kotlin.Unit
|
||||
|
||||
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
|
||||
@kotlin.jvm.JvmName(name = "other") public final fun simple(): kotlin.Unit
|
||||
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
|
||||
}
|
||||
-4
@@ -3,22 +3,18 @@
|
||||
|
||||
fun foo(x: Int): Int = 0
|
||||
|
||||
@JvmName("fooUInt")
|
||||
fun foo(x: UInt): String = ""
|
||||
fun foo(x: UByte): String = ""
|
||||
fun foo(x: UShort): String = ""
|
||||
fun foo(x: ULong): String = ""
|
||||
|
||||
fun fooByte(x: Byte): Int = 0
|
||||
@JvmName("fooUByte")
|
||||
fun fooByte(x: UByte): String = ""
|
||||
|
||||
fun fooShort(x: Short): Int = 0
|
||||
@JvmName("fooUByte")
|
||||
fun fooShort(x: UShort): String = ""
|
||||
|
||||
fun fooLong(x: Long): Int = 0
|
||||
@JvmName("fooULong")
|
||||
fun fooLong(x: ULong): String = ""
|
||||
|
||||
fun test() {
|
||||
|
||||
+4
-4
@@ -2,13 +2,13 @@ package
|
||||
|
||||
public fun foo(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
public fun foo(/*0*/ x: kotlin.UByte): kotlin.String
|
||||
@kotlin.jvm.JvmName(name = "fooUInt") public fun foo(/*0*/ x: kotlin.UInt): kotlin.String
|
||||
public fun foo(/*0*/ x: kotlin.UInt): kotlin.String
|
||||
public fun foo(/*0*/ x: kotlin.ULong): kotlin.String
|
||||
public fun foo(/*0*/ x: kotlin.UShort): kotlin.String
|
||||
public fun fooByte(/*0*/ x: kotlin.Byte): kotlin.Int
|
||||
@kotlin.jvm.JvmName(name = "fooUByte") public fun fooByte(/*0*/ x: kotlin.UByte): kotlin.String
|
||||
public fun fooByte(/*0*/ x: kotlin.UByte): kotlin.String
|
||||
public fun fooLong(/*0*/ x: kotlin.Long): kotlin.Int
|
||||
@kotlin.jvm.JvmName(name = "fooULong") public fun fooLong(/*0*/ x: kotlin.ULong): kotlin.String
|
||||
public fun fooLong(/*0*/ x: kotlin.ULong): kotlin.String
|
||||
public fun fooShort(/*0*/ x: kotlin.Short): kotlin.Int
|
||||
@kotlin.jvm.JvmName(name = "fooUByte") public fun fooShort(/*0*/ x: kotlin.UShort): kotlin.String
|
||||
public fun fooShort(/*0*/ x: kotlin.UShort): kotlin.String
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
+5
@@ -243,6 +243,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmNameOnMangledNames.kt")
|
||||
public void testJvmNameOnMangledNames() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileClassPart.kt")
|
||||
public void testMultifileClassPart() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt");
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+5
@@ -243,6 +243,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmName.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmNameOnMangledNames.kt")
|
||||
public void testJvmNameOnMangledNames() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmNameOnMangledNames.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileClassPart.kt")
|
||||
public void testMultifileClassPart() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt");
|
||||
|
||||
+5
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.load.kotlin.getRepresentativeUpperBound
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.security.MessageDigest
|
||||
@@ -29,11 +30,14 @@ fun requiresFunctionNameMangling(valueParameterTypes: List<KotlinType>): Boolean
|
||||
return valueParameterTypes.any { it.requiresFunctionNameMangling() }
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
||||
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
||||
|
||||
private fun KotlinType.requiresFunctionNameMangling() =
|
||||
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
||||
|
||||
private fun KotlinType.isInlineClassThatRequiresMangling() =
|
||||
isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor)
|
||||
constructor.declarationDescriptor?.isInlineClassThatRequiresMangling() == true
|
||||
|
||||
private fun isDontMangleClass(classDescriptor: ClassDescriptor) =
|
||||
classDescriptor.fqNameSafe == DescriptorUtils.RESULT_FQ_NAME
|
||||
|
||||
Reference in New Issue
Block a user