JVM: Fix reflection tests for new IC ABI

This commit is contained in:
Dmitry Petrov
2020-05-07 21:30:31 +03:00
parent b5bd3604b1
commit dc9f64fc9d
18 changed files with 214 additions and 47 deletions
@@ -407,7 +407,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
if (generateBody) { if (generateBody) {
mv.visitCode(); mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, descriptor, state); CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, descriptor, state);
iv.areturn(JAVA_STRING_TYPE); iv.areturn(JAVA_STRING_TYPE);
FunctionCodegen.endVisit(iv, "function reference getSignature", element); FunctionCodegen.endVisit(iv, "function reference getSignature", element);
} }
@@ -465,7 +465,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
assert functionReferenceTarget != null : "No function reference target: " + funDescriptor; assert functionReferenceTarget != null : "No function reference target: " + funDescriptor;
generateCallableReferenceDeclarationContainerClass(iv, functionReferenceTarget, state); generateCallableReferenceDeclarationContainerClass(iv, functionReferenceTarget, state);
iv.aconst(functionReferenceTarget.getName().asString()); iv.aconst(functionReferenceTarget.getName().asString());
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, functionReferenceTarget, state); CallableReferenceUtilKt.generateFunctionReferenceSignature(iv, functionReferenceTarget, state);
int flags = int flags =
getCallableReferenceTopLevelFlag(functionReferenceTarget) + getCallableReferenceTopLevelFlag(functionReferenceTarget) +
(calculateFunctionReferenceFlags(functionReferenceCall, funDescriptor) << 1); (calculateFunctionReferenceFlags(functionReferenceCall, funDescriptor) << 1);
@@ -679,7 +679,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
} }
iv.aconst(property.getName().asString()); iv.aconst(property.getName().asString());
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, property, state); CallableReferenceUtilKt.generatePropertyReferenceSignature(iv, property, state);
superCtorArgTypes.add(JAVA_STRING_TYPE); superCtorArgTypes.add(JAVA_STRING_TYPE);
superCtorArgTypes.add(JAVA_STRING_TYPE); superCtorArgTypes.add(JAVA_STRING_TYPE);
@@ -13,12 +13,13 @@ enum class OwnerKind {
PACKAGE, PACKAGE,
IMPLEMENTATION, IMPLEMENTATION,
DEFAULT_IMPLS, DEFAULT_IMPLS,
ERASED_INLINE_CLASS; ERASED_INLINE_CLASS,
PROPERTY_REFERENCE_SIGNATURE;
companion object { companion object {
fun getMemberOwnerKind(descriptor: DeclarationDescriptor): OwnerKind = when (descriptor) { fun getMemberOwnerKind(descriptor: DeclarationDescriptor): OwnerKind = when (descriptor) {
is PackageFragmentDescriptor -> OwnerKind.PACKAGE is PackageFragmentDescriptor -> PACKAGE
is ClassDescriptor -> OwnerKind.IMPLEMENTATION is ClassDescriptor -> IMPLEMENTATION
else -> throw AssertionError("Unexpected declaration container: $this") else -> throw AssertionError("Unexpected declaration container: $this")
} }
} }
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
@@ -52,6 +51,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND; import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
import static org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt.isTopLevelInJvmMultifileClass;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
@@ -135,10 +135,10 @@ public class PropertyCodegen {
boolean isDefaultGetterAndSetter = isDefaultAccessor(getter) && isDefaultAccessor(setter); boolean isDefaultGetterAndSetter = isDefaultAccessor(getter) && isDefaultAccessor(setter);
if (isAccessorNeeded(declaration, descriptor, getter, isDefaultGetterAndSetter)) { if (isAccessorNeeded(descriptor, getter, isDefaultGetterAndSetter)) {
generateGetter(descriptor, getter); generateGetter(descriptor, getter);
} }
if (isAccessorNeeded(declaration, descriptor, setter, isDefaultGetterAndSetter)) { if (isAccessorNeeded(descriptor, setter, isDefaultGetterAndSetter)) {
generateSetter(descriptor, setter); generateSetter(descriptor, setter);
} }
} }
@@ -167,17 +167,40 @@ public class PropertyCodegen {
generateSyntheticMethodIfNeeded(descriptor, isBackingFieldOwner); generateSyntheticMethodIfNeeded(descriptor, isBackingFieldOwner);
} }
private boolean isAccessorNeeded(
@NotNull PropertyDescriptor descriptor,
@Nullable KtPropertyAccessor accessor,
boolean isDefaultGetterAndSetter
) {
return isAccessorNeeded(descriptor, accessor, isDefaultGetterAndSetter, kind);
}
public static boolean isReferenceablePropertyWithGetter(@NotNull PropertyDescriptor descriptor) {
PsiElement psiElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
KtDeclaration ktDeclaration = psiElement instanceof KtDeclaration ? (KtDeclaration) psiElement : null;
if (ktDeclaration instanceof KtProperty) {
KtProperty ktProperty = (KtProperty) ktDeclaration;
boolean isDefaultGetterAndSetter =
isDefaultAccessor(ktProperty.getGetter()) && isDefaultAccessor(ktProperty.getSetter());
return isAccessorNeeded(descriptor, ktProperty.getGetter(), isDefaultGetterAndSetter, OwnerKind.IMPLEMENTATION);
} else if (ktDeclaration instanceof KtParameter) {
return isAccessorNeeded(descriptor, null, true, OwnerKind.IMPLEMENTATION);
} else {
return isAccessorNeeded(descriptor, null, false, OwnerKind.IMPLEMENTATION);
}
}
/** /**
* Determines if it's necessary to generate an accessor to the property, i.e. if this property can be referenced via getter/setter * Determines if it's necessary to generate an accessor to the property, i.e. if this property can be referenced via getter/setter
* for any reason * for any reason
* *
* @see JvmCodegenUtil#couldUseDirectAccessToProperty * @see JvmCodegenUtil#couldUseDirectAccessToProperty
*/ */
private boolean isAccessorNeeded( private static boolean isAccessorNeeded(
@NotNull KtProperty declaration,
@NotNull PropertyDescriptor descriptor, @NotNull PropertyDescriptor descriptor,
@Nullable KtPropertyAccessor accessor, @Nullable KtPropertyAccessor accessor,
boolean isDefaultGetterAndSetter boolean isDefaultGetterAndSetter,
OwnerKind kind
) { ) {
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false; if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
@@ -187,7 +210,8 @@ public class PropertyCodegen {
if (kind == OwnerKind.DEFAULT_IMPLS && isDefaultAccessor) return false; if (kind == OwnerKind.DEFAULT_IMPLS && isDefaultAccessor) return false;
// Delegated or extension properties can only be referenced via accessors // Delegated or extension properties can only be referenced via accessors
if (declaration.hasDelegate() || declaration.getReceiverTypeReference() != null) return true; //noinspection deprecation
if (descriptor.isDelegated() || descriptor.getExtensionReceiverParameter() != null) return true;
// Companion object properties should have accessors for non-private properties because these properties can be referenced // Companion object properties should have accessors for non-private properties because these properties can be referenced
// via getter/setter. But these accessors getter/setter are not required for private properties that have a default getter // via getter/setter. But these accessors getter/setter are not required for private properties that have a default getter
@@ -201,7 +225,7 @@ public class PropertyCodegen {
} }
// Non-const properties from multifile classes have accessors regardless of visibility // Non-const properties from multifile classes have accessors regardless of visibility
if (isTopLevelPropertyInMultifileClass(declaration, descriptor)) return true; if (isTopLevelInJvmMultifileClass(descriptor)) return true;
// Private class properties have accessors only in cases when those accessors are non-trivial // Private class properties have accessors only in cases when those accessors are non-trivial
if (Visibilities.isPrivate(descriptor.getVisibility())) { if (Visibilities.isPrivate(descriptor.getVisibility())) {
@@ -215,15 +239,12 @@ public class PropertyCodegen {
return !isDefaultAccessor; return !isDefaultAccessor;
} }
return true; // Non-public API (private and internal) primary vals of inline classes don't have getter
} if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(descriptor) && !descriptor.getVisibility().isPublicAPI()) {
return false;
}
private static boolean isTopLevelPropertyInMultifileClass( return true;
@NotNull KtProperty declaration,
@NotNull PropertyDescriptor descriptor
) {
return descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor &&
JvmFileClassUtilKt.isInsideJvmMultifileClassFile(declaration);
} }
private static boolean areAccessorsNeededForPrimaryConstructorProperty( private static boolean areAccessorsNeededForPrimaryConstructorProperty(
@@ -118,7 +118,7 @@ class PropertyReferenceCodegen(
aconst(target.name.asString()) aconst(target.name.asString())
} }
generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) { generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) {
generateCallableReferenceSignature(this, target, state) generatePropertyReferenceSignature(this, target, state)
} }
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) { generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
generateCallableReferenceDeclarationContainer(this, target, state) generateCallableReferenceDeclarationContainer(this, target, state)
@@ -148,7 +148,7 @@ class PropertyReferenceCodegen(
if (isOptimizedPropertyReferenceSupertype(superAsmType)) { if (isOptimizedPropertyReferenceSupertype(superAsmType)) {
generateCallableReferenceDeclarationContainerClass(this, target, state) generateCallableReferenceDeclarationContainerClass(this, target, state)
aconst(target.name.asString()) aconst(target.name.asString())
generateCallableReferenceSignature(this, target, state) generatePropertyReferenceSignature(this, target, state)
aconst(getCallableReferenceTopLevelFlag(target)) aconst(getCallableReferenceTopLevelFlag(target))
superCtorArgTypes.add(JAVA_CLASS_TYPE) superCtorArgTypes.add(JAVA_CLASS_TYPE)
superCtorArgTypes.add(JAVA_STRING_TYPE) superCtorArgTypes.add(JAVA_STRING_TYPE)
@@ -168,11 +168,15 @@ private fun isTopLevelCallableReference(descriptor: CallableDescriptor): Boolean
internal fun getCallableReferenceTopLevelFlag(descriptor: CallableDescriptor): Int = internal fun getCallableReferenceTopLevelFlag(descriptor: CallableDescriptor): Int =
if (isTopLevelCallableReference(descriptor)) 1 else 0 if (isTopLevelCallableReference(descriptor)) 1 else 0
internal fun generateCallableReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) { internal fun generateFunctionReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) {
iv.aconst(getSignatureString(callable, state)) iv.aconst(getSignatureString(callable, state))
} }
private fun getSignatureString(callable: CallableDescriptor, state: GenerationState): String { internal fun generatePropertyReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) {
iv.aconst(getSignatureString(callable, state, isPropertySignature = true))
}
private fun getSignatureString(callable: CallableDescriptor, state: GenerationState, isPropertySignature: Boolean = false): String {
if (callable is LocalVariableDescriptor) { if (callable is LocalVariableDescriptor) {
val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable) val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable)
?: throw AssertionError("No delegated property metadata owner for $callable") ?: throw AssertionError("No delegated property metadata owner for $callable")
@@ -198,10 +202,13 @@ private fun getSignatureString(callable: CallableDescriptor, state: GenerationSt
else -> error("Unsupported callable reference: $callable") else -> error("Unsupported callable reference: $callable")
} }
val declaration = DescriptorUtils.unwrapFakeOverride(accessor).original val declaration = DescriptorUtils.unwrapFakeOverride(accessor).original
val method = val method = when {
if (callable.containingDeclaration.isInlineClass() && !declaration.isGetterOfUnderlyingPropertyOfInlineClass()) callable.containingDeclaration.isInlineClass() && !declaration.isGetterOfUnderlyingPropertyOfInlineClass() ->
state.typeMapper.mapSignatureForInlineErasedClassSkipGeneric(declaration).asmMethod state.typeMapper.mapSignatureForInlineErasedClassSkipGeneric(declaration).asmMethod
else isPropertySignature ->
state.typeMapper.mapPropertyReferenceSignature(declaration)
else ->
state.typeMapper.mapAsmMethod(declaration) state.typeMapper.mapAsmMethod(declaration)
}
return method.name + method.descriptor return method.name + method.descriptor
} }
@@ -47,7 +47,7 @@ class PsiInlineIntrinsicsSupport(private val state: GenerationState) : ReifiedTy
v.aconst(descriptor.arity) v.aconst(descriptor.arity)
generateCallableReferenceDeclarationContainerClass(v, descriptor, state) generateCallableReferenceDeclarationContainerClass(v, descriptor, state)
v.aconst(descriptor.name.asString()) v.aconst(descriptor.name.asString())
generateCallableReferenceSignature(v, descriptor, state) generateFunctionReferenceSignature(v, descriptor, state)
v.aconst(getCallableReferenceTopLevelFlag(descriptor)) v.aconst(getCallableReferenceTopLevelFlag(descriptor))
v.invokespecial( v.invokespecial(
FUNCTION_REFERENCE_IMPL.internalName, "<init>", FUNCTION_REFERENCE_IMPL.internalName, "<init>",
@@ -683,6 +683,15 @@ class KotlinTypeMapper @JvmOverloads constructor(
} else newName } else newName
} }
private fun CallableMemberDescriptor.isPropertyWithGetterSignaturePresent(): Boolean {
val propertyDescriptor = when (this) {
is PropertyDescriptor -> this
is PropertyAccessorDescriptor -> correspondingProperty
else -> return false
}
return PropertyCodegen.isReferenceablePropertyWithGetter(propertyDescriptor)
}
private fun getModuleName(descriptor: CallableMemberDescriptor): String { private fun getModuleName(descriptor: CallableMemberDescriptor): String {
return getJvmModuleNameForDeserializedDescriptor(descriptor) ?: moduleName return getJvmModuleNameForDeserializedDescriptor(descriptor) ?: moduleName
} }
@@ -691,6 +700,10 @@ class KotlinTypeMapper @JvmOverloads constructor(
return mapSignature(descriptor).asmMethod return mapSignature(descriptor).asmMethod
} }
fun mapPropertyReferenceSignature(descriptor: FunctionDescriptor): Method {
return mapSignature(descriptor, OwnerKind.PROPERTY_REFERENCE_SIGNATURE, true).asmMethod
}
fun mapAsmMethod(descriptor: FunctionDescriptor, kind: OwnerKind): Method { fun mapAsmMethod(descriptor: FunctionDescriptor, kind: OwnerKind): Method {
return mapSignature(descriptor, kind, true).asmMethod return mapSignature(descriptor, kind, true).asmMethod
} }
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.resolve.jvm.* import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameMangling
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound import org.jetbrains.kotlin.types.typeUtil.representativeUpperBound
import java.security.MessageDigest import java.security.MessageDigest
@@ -24933,6 +24933,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");
@@ -19,11 +19,15 @@ package org.jetbrains.kotlin.fileClasses
import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
@@ -40,19 +44,19 @@ object JvmFileClassUtil {
private const val MULTIFILE_PART_NAME_DELIMITER = "__" private const val MULTIFILE_PART_NAME_DELIMITER = "__"
fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName = fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName =
descriptor.getImplClassNameForDeserialized()?.fqNameForTopLevelClassMaybeWithDollars descriptor.getImplClassNameForDeserialized()?.fqNameForTopLevelClassMaybeWithDollars
?: error("No implClassName for $descriptor") ?: error("No implClassName for $descriptor")
@JvmStatic @JvmStatic
fun getFileClassInternalName(file: KtFile): String = fun getFileClassInternalName(file: KtFile): String =
getFileClassInfoNoResolve(file).fileClassFqName.internalNameWithoutInnerClasses getFileClassInfoNoResolve(file).fileClassFqName.internalNameWithoutInnerClasses
@JvmStatic @JvmStatic
fun getFacadeClassInternalName(file: KtFile): String = fun getFacadeClassInternalName(file: KtFile): String =
getFileClassInfoNoResolve(file).facadeClassFqName.internalNameWithoutInnerClasses getFileClassInfoNoResolve(file).facadeClassFqName.internalNameWithoutInnerClasses
private fun manglePartName(facadeName: String, fileName: String): String = private fun manglePartName(facadeName: String, fileName: String): String =
"$facadeName$MULTIFILE_PART_NAME_DELIMITER${PackagePartClassUtils.getFilePartShortName(fileName)}" "$facadeName$MULTIFILE_PART_NAME_DELIMITER${PackagePartClassUtils.getFilePartShortName(fileName)}"
@JvmStatic @JvmStatic
fun getFileClassInfoNoResolve(file: KtFile): JvmFileClassInfo { fun getFileClassInfoNoResolve(file: KtFile): JvmFileClassInfo {
@@ -64,8 +68,8 @@ object JvmFileClassUtil {
val facadeClassFqName = packageFqName.child(Name.identifier(simpleName)) val facadeClassFqName = packageFqName.child(Name.identifier(simpleName))
when { when {
parsedAnnotations.isMultifileClass -> JvmMultifileClassPartInfo( parsedAnnotations.isMultifileClass -> JvmMultifileClassPartInfo(
fileClassFqName = packageFqName.child(Name.identifier(manglePartName(simpleName, file.name))), fileClassFqName = packageFqName.child(Name.identifier(manglePartName(simpleName, file.name))),
facadeClassFqName = facadeClassFqName facadeClassFqName = facadeClassFqName
) )
else -> JvmSimpleFileClassInfo(facadeClassFqName, true) else -> JvmSimpleFileClassInfo(facadeClassFqName, true)
} }
@@ -90,9 +94,9 @@ object JvmFileClassUtil {
@JvmStatic @JvmStatic
fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? = fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? =
file.fileAnnotationList?.annotationEntries?.firstOrNull { file.fileAnnotationList?.annotationEntries?.firstOrNull {
it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName
} }
private fun getLiteralStringFromAnnotation(annotation: KtAnnotationEntry): String? { private fun getLiteralStringFromAnnotation(annotation: KtAnnotationEntry): String? {
val argumentExpression = annotation.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null val argumentExpression = annotation.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
@@ -108,8 +112,8 @@ val KtFile.javaFileFacadeFqName: FqName
get() { get() {
return CachedValuesManager.getCachedValue(this) { return CachedValuesManager.getCachedValue(this) {
val facadeFqName = val facadeFqName =
if (isCompiled) packageFqName.child(Name.identifier(virtualFile.nameWithoutExtension)) if (isCompiled) packageFqName.child(Name.identifier(virtualFile.nameWithoutExtension))
else JvmFileClassUtil.getFileClassInfoNoResolve(this).facadeClassFqName else JvmFileClassUtil.getFileClassInfoNoResolve(this).facadeClassFqName
if (!Name.isValidIdentifier(facadeFqName.shortName().identifier)) { if (!Name.isValidIdentifier(facadeFqName.shortName().identifier)) {
LOG.error( LOG.error(
@@ -124,10 +128,26 @@ val KtFile.javaFileFacadeFqName: FqName
private val LOG = Logger.getInstance("JvmFileClassUtil") private val LOG = Logger.getInstance("JvmFileClassUtil")
fun KtDeclaration.isInsideJvmMultifileClassFile() = JvmFileClassUtil.findAnnotationEntryOnFileNoResolve( fun KtDeclaration.isInsideJvmMultifileClassFile() =
containingKtFile, JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(containingKtFile, JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT) != null
JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT
) != null fun DeclarationDescriptor.isTopLevelInJvmMultifileClass(): Boolean {
if (containingDeclaration !is PackageFragmentDescriptor) return false
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(this)
if (declaration is KtDeclaration) {
return declaration.isInsideJvmMultifileClassFile()
}
if (this is DeserializedMemberDescriptor) {
val containerSource = containerSource
if (containerSource is JvmPackagePartSource && containerSource.facadeClassName != null) {
return true
}
}
return false
}
val FqName.internalNameWithoutInnerClasses: String val FqName.internalNameWithoutInnerClasses: String
get() = JvmClassName.byFqNameWithoutInnerClasses(this).internalName get() = JvmClassName.byFqNameWithoutInnerClasses(this).internalName
@@ -0,0 +1,24 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
// MODULE: main(lib)
// FILE: privateCompanionObjectValInDifferentModule.kt
import lib.*
fun box() = Host.ref.call().s
// MODULE: lib
// FILE: lib.kt
package lib
import kotlin.reflect.jvm.isAccessible
inline class S(val s: String)
class Host {
companion object {
private val ok = S("OK")
val ref = ::ok.apply { isAccessible = true }
}
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
// MODULE: main(lib)
// FILE: privateTopLevelValInDifferentModule.kt
import lib.*
fun box() = ref.call().s
// MODULE: lib
// FILE: lib.kt
package lib
import kotlin.reflect.jvm.isAccessible
inline class S(val s: String)
private val ok = S("OK")
val ref = ::ok.apply { isAccessible = true }
@@ -26519,6 +26519,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");
@@ -24153,6 +24153,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");
@@ -24933,6 +24933,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");
@@ -21184,6 +21184,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");
@@ -21199,6 +21199,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/primaryValOfInlineClass.kt");
} }
@TestMetadata("privateCompanionObjectValInDifferentModule.kt")
public void testPrivateCompanionObjectValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/privateTopLevelValInDifferentModule.kt");
}
@TestMetadata("properties.kt") @TestMetadata("properties.kt")
public void testProperties() throws Exception { public void testProperties() throws Exception {
runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt"); runTest("compiler/testData/codegen/box/reflection/call/inlineClasses/properties.kt");