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.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
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.VOLATILE_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.findSynchronizedAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation
|
||||||
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.jvm.requiresFunctionNameMangling
|
||||||
|
|
||||||
class LocalFunInlineChecker : DeclarationChecker {
|
class LocalFunInlineChecker : DeclarationChecker {
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
@@ -143,6 +146,10 @@ class JvmNameAnnotationChecker : DeclarationChecker {
|
|||||||
if (descriptor is CallableMemberDescriptor) {
|
if (descriptor is CallableMemberDescriptor) {
|
||||||
if (DescriptorUtils.isOverride(descriptor) || descriptor.isOverridable) {
|
if (DescriptorUtils.isOverride(descriptor) || descriptor.isOverridable) {
|
||||||
diagnosticHolder.report(ErrorsJvm.INAPPLICABLE_JVM_NAME.on(annotationEntry))
|
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
|
fun foo(x: Int): Int = 0
|
||||||
|
|
||||||
@JvmName("fooUInt")
|
|
||||||
fun foo(x: UInt): String = ""
|
fun foo(x: UInt): String = ""
|
||||||
fun foo(x: UByte): String = ""
|
fun foo(x: UByte): String = ""
|
||||||
fun foo(x: UShort): String = ""
|
fun foo(x: UShort): String = ""
|
||||||
fun foo(x: ULong): String = ""
|
fun foo(x: ULong): String = ""
|
||||||
|
|
||||||
fun fooByte(x: Byte): Int = 0
|
fun fooByte(x: Byte): Int = 0
|
||||||
@JvmName("fooUByte")
|
|
||||||
fun fooByte(x: UByte): String = ""
|
fun fooByte(x: UByte): String = ""
|
||||||
|
|
||||||
fun fooShort(x: Short): Int = 0
|
fun fooShort(x: Short): Int = 0
|
||||||
@JvmName("fooUByte")
|
|
||||||
fun fooShort(x: UShort): String = ""
|
fun fooShort(x: UShort): String = ""
|
||||||
|
|
||||||
fun fooLong(x: Long): Int = 0
|
fun fooLong(x: Long): Int = 0
|
||||||
@JvmName("fooULong")
|
|
||||||
fun fooLong(x: ULong): String = ""
|
fun fooLong(x: ULong): String = ""
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|||||||
+4
-4
@@ -2,13 +2,13 @@ package
|
|||||||
|
|
||||||
public fun foo(/*0*/ x: kotlin.Int): kotlin.Int
|
public fun foo(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
public fun foo(/*0*/ x: kotlin.UByte): kotlin.String
|
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.ULong): kotlin.String
|
||||||
public fun foo(/*0*/ x: kotlin.UShort): kotlin.String
|
public fun foo(/*0*/ x: kotlin.UShort): kotlin.String
|
||||||
public fun fooByte(/*0*/ x: kotlin.Byte): kotlin.Int
|
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
|
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
|
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
|
public fun test(): kotlin.Unit
|
||||||
|
|||||||
+5
@@ -243,6 +243,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/jvmName.kt");
|
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")
|
@TestMetadata("multifileClassPart.kt")
|
||||||
public void testMultifileClassPart() throws Exception {
|
public void testMultifileClassPart() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt");
|
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");
|
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")
|
@TestMetadata("multifileClassPart.kt")
|
||||||
public void testMultifileClassPart() throws Exception {
|
public void testMultifileClassPart() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/multifileClassPart.kt");
|
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.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
@@ -29,11 +30,14 @@ fun requiresFunctionNameMangling(valueParameterTypes: List<KotlinType>): Boolean
|
|||||||
return valueParameterTypes.any { it.requiresFunctionNameMangling() }
|
return valueParameterTypes.any { it.requiresFunctionNameMangling() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DeclarationDescriptor.isInlineClassThatRequiresMangling(): Boolean =
|
||||||
|
isInlineClass() && !isDontMangleClass(this as ClassDescriptor)
|
||||||
|
|
||||||
private fun KotlinType.requiresFunctionNameMangling() =
|
private fun KotlinType.requiresFunctionNameMangling() =
|
||||||
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
||||||
|
|
||||||
private fun KotlinType.isInlineClassThatRequiresMangling() =
|
private fun KotlinType.isInlineClassThatRequiresMangling() =
|
||||||
isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor)
|
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