Fix codegen for multifile class parts with type aliases only
#KT-20337 Fixed
This commit is contained in:
@@ -368,7 +368,7 @@ class MultifileClassCodegenImpl(
|
||||
}
|
||||
|
||||
private fun KtFile.hasDeclarationsForPartClass() =
|
||||
CodegenUtil.getActualDeclarations(this).any { it is KtProperty || it is KtFunction }
|
||||
CodegenUtil.getActualDeclarations(this).any { it is KtProperty || it is KtFunction || it is KtTypeAlias }
|
||||
|
||||
private fun getCompiledPackageFragment(
|
||||
facadeFqName: FqName, state: GenerationState
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
@@ -29,16 +28,13 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtTypeAlias
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.MultifileClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||
import java.util.*
|
||||
|
||||
class MultifileClassPartCodegen(
|
||||
v: ClassBuilder,
|
||||
@@ -162,25 +158,7 @@ class MultifileClassPartCodegen(
|
||||
}
|
||||
|
||||
override fun generateKotlinMetadataAnnotation() {
|
||||
val members = ArrayList<DeclarationDescriptor>()
|
||||
for (declaration in CodegenUtil.getActualDeclarations(element)) {
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> {
|
||||
val functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration)
|
||||
members.add(functionDescriptor ?: throw AssertionError("Function ${declaration.name} is not bound in ${element.name}"))
|
||||
}
|
||||
is KtProperty -> {
|
||||
val property = bindingContext.get(BindingContext.VARIABLE, declaration)
|
||||
members.add(property ?: throw AssertionError("Property ${declaration.name} is not bound in ${element.name}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val extension = JvmSerializerExtension(v.serializationBindings, state)
|
||||
val serializer = DescriptorSerializer.createTopLevel(extension)
|
||||
val builder = serializer.packagePartProto(packageFragment.fqName, members)
|
||||
extension.serializeJvmPackage(builder, partType)
|
||||
val packageProto = builder.build()
|
||||
val (serializer, packageProto) = PackagePartCodegen.serializePackagePartMembers(this, partType)
|
||||
|
||||
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.Pair;
|
||||
import kotlin.Unit;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
||||
@@ -25,9 +27,6 @@ import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||
@@ -101,34 +100,42 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
||||
|
||||
@Override
|
||||
protected void generateKotlinMetadataAnnotation() {
|
||||
List<DeclarationDescriptor> members = new ArrayList<>();
|
||||
for (KtDeclaration declaration : CodegenUtil.getActualDeclarations(element)) {
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
members.add(functionDescriptor);
|
||||
}
|
||||
else if (declaration instanceof KtProperty) {
|
||||
VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
members.add(property);
|
||||
}
|
||||
else if (declaration instanceof KtTypeAlias) {
|
||||
TypeAliasDescriptor typeAlias = bindingContext.get(BindingContext.TYPE_ALIAS, declaration);
|
||||
members.add(typeAlias);
|
||||
}
|
||||
}
|
||||
|
||||
JvmSerializerExtension extension = new JvmSerializerExtension(v.getSerializationBindings(), state);
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
|
||||
ProtoBuf.Package.Builder builder = serializer.packagePartProto(element.getPackageFqName(), members);
|
||||
extension.serializeJvmPackage(builder, packagePartType);
|
||||
ProtoBuf.Package packageProto = builder.build();
|
||||
Pair<DescriptorSerializer, ProtoBuf.Package> serializedPart = serializePackagePartMembers(this, packagePartType);
|
||||
|
||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
||||
writeAnnotationData(av, serializer, packageProto);
|
||||
writeAnnotationData(av, serializedPart.getFirst(), serializedPart.getSecond());
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static Pair<DescriptorSerializer, ProtoBuf.Package> serializePackagePartMembers(
|
||||
@NotNull MemberCodegen<? extends KtFile> codegen,
|
||||
@NotNull Type packagePartType
|
||||
) {
|
||||
BindingContext bindingContext = codegen.bindingContext;
|
||||
List<DeclarationDescriptor> members = CollectionsKt.mapNotNull(CodegenUtil.getActualDeclarations(codegen.element), declaration -> {
|
||||
if (declaration instanceof KtNamedFunction) {
|
||||
return bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
}
|
||||
else if (declaration instanceof KtProperty) {
|
||||
return bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
}
|
||||
else if (declaration instanceof KtTypeAlias) {
|
||||
return bindingContext.get(BindingContext.TYPE_ALIAS, declaration);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
JvmSerializerExtension extension = new JvmSerializerExtension(codegen.v.getSerializationBindings(), codegen.state);
|
||||
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
|
||||
ProtoBuf.Package.Builder builder = serializer.packagePartProto(codegen.element.getPackageFqName(), members);
|
||||
extension.serializeJvmPackage(builder, packagePartType);
|
||||
|
||||
return new Pair<>(serializer, builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSyntheticPartsAfterBody() {
|
||||
generateSyntheticAccessors();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// FILE: A.kt
|
||||
|
||||
@file:[JvmName("Test") JvmMultifileClass]
|
||||
|
||||
typealias S = String
|
||||
typealias LS = List<S>
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
import java.util.Arrays
|
||||
|
||||
fun box(): S {
|
||||
val l: LS = Arrays.asList("OK")
|
||||
return l[0]
|
||||
}
|
||||
+6
@@ -168,6 +168,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multifileClassWithTypealias.kt")
|
||||
public void testMultifileClassWithTypealias() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/multifileClassWithTypealias.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClass.kt")
|
||||
public void testNestedClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/nestedClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user