diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt index 2c30b8fb8d6..937cc81d924 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.PropertyCodegen import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.idea.KotlinLanguage @@ -35,6 +36,7 @@ import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.EnumValue @@ -51,7 +53,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult companion object { // This property may be removed once IntelliJ versions earlier than 2018.3 become unsupported - // And usages of that property may be replaced with relevant registry change + // And usages of that property may be replaced with relevant registry key @Volatile @TestOnly var forceUsingUltraLightClasses = false @@ -334,7 +336,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult val name = if (isConstructor) this.name - else mangleIfNeeded(listOf(ktFunction), ktFunction.name ?: SpecialNames.NO_NAME_PROVIDED.asString()) + else computeMethodName(ktFunction, ktFunction.name ?: SpecialNames.NO_NAME_PROVIDED.asString()) val method = lightMethod(name.orEmpty(), ktFunction, forceStatic) val wrapper = KtUltraLightMethod(method, ktFunction, support, this) @@ -437,21 +439,30 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult ).setConstructor(declaration is KtConstructor<*>) } - private fun mangleIfNeeded(declarations: List, name: String): String { - for (declaration in declarations) { - if (declaration.hasModifier(PRIVATE_KEYWORD) || - declaration.hasModifier(PROTECTED_KEYWORD) || - declaration.hasModifier(PUBLIC_KEYWORD) - ) { - return name - } - if (isInternal(declaration) && declaration.resolve()?.isPublishedApi() != true) { - return KotlinTypeMapper.InternalNameMapper.mangleInternalName(name, support.moduleName) - } + private fun computeMethodName(declaration: KtDeclaration, name: String): String { + if (declaration.hasAnnotation(DescriptorUtils.JVM_NAME)) { + val newName = (declaration.resolve() as? Annotated)?.let(DescriptorUtils::getJvmName) + if (newName != null) return newName } + + if (isInternalNonPublishedApi(declaration)) return KotlinTypeMapper.InternalNameMapper.mangleInternalName(name, support.moduleName) return name } + private tailrec fun isInternalNonPublishedApi(declaration: KtDeclaration): Boolean { + if (declaration.hasModifier(PRIVATE_KEYWORD) || + declaration.hasModifier(PROTECTED_KEYWORD) || + declaration.hasModifier(PUBLIC_KEYWORD) + ) { + return false + } + + if (isInternal(declaration) && declaration.resolve()?.isPublishedApi() != true) return true + + val containingProperty = (declaration as? KtPropertyAccessor)?.property ?: return false + return isInternalNonPublishedApi(containingProperty) + } + private fun KtAnnotated.hasAnnotation(name: FqName) = support.findAnnotation(this, name) != null private fun isInternal(f: KtDeclaration): Boolean { @@ -491,7 +502,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult val result = arrayListOf() if (needsAccessor(ktGetter)) { - val getterName = mangleIfNeeded(listOfNotNull(ktGetter, declaration), JvmAbi.getterName(propertyName)) + val getterName = computeMethodName(ktGetter ?: declaration, JvmAbi.getterName(propertyName)) val getterPrototype = lightMethod(getterName, ktGetter ?: declaration, onlyJvmStatic) val getterWrapper = KtUltraLightMethod(getterPrototype, declaration, support, this) val getterType: PsiType by lazyPub { methodReturnType(declaration, getterWrapper) } @@ -501,7 +512,7 @@ class KtUltraLightClass(classOrObject: KtClassOrObject, private val support: Ult } if (mutable && needsAccessor(ktSetter)) { - val setterName = mangleIfNeeded(listOfNotNull(ktSetter, declaration), JvmAbi.setterName(propertyName)) + val setterName = computeMethodName(ktSetter ?: declaration, JvmAbi.setterName(propertyName)) val setterPrototype = lightMethod(setterName, ktSetter ?: declaration, onlyJvmStatic) .setMethodReturnType(PsiType.VOID) val setterWrapper = KtUltraLightMethod(setterPrototype, declaration, support, this) diff --git a/compiler/testData/asJava/ultraLightClasses/jvmName.kt b/compiler/testData/asJava/ultraLightClasses/jvmName.kt index 58db822993d..ec805a01279 100644 --- a/compiler/testData/asJava/ultraLightClasses/jvmName.kt +++ b/compiler/testData/asJava/ultraLightClasses/jvmName.kt @@ -1,4 +1,3 @@ -/** should load cls */ class C { var rwProp: Int @JvmName("get_rwProp") @@ -8,4 +7,8 @@ class C { fun getRwProp(): Int = 123 fun setRwProp(v: Int) {} + + fun foo(x: List) {} + @JvmName("fooInt") + fun foo(x: List) {} } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 492155bd69a..a97e01e69af 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers @@ -119,6 +120,7 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG if (name == JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME.shortName()) return false if (name == JVM_OVERLOADS_FQ_NAME.shortName()) return false if (name == JVM_SYNTHETIC_ANNOTATION_FQ_NAME.shortName()) return false + if (name == DescriptorUtils.JVM_NAME.shortName()) return false return true }