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() =
|
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(
|
private fun getCompiledPackageFragment(
|
||||||
facadeFqName: FqName, state: GenerationState
|
facadeFqName: FqName, state: GenerationState
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen
|
|||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext
|
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.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
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.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtTypeAlias
|
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.MultifileClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
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.MethodVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodInsnNode
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MultifileClassPartCodegen(
|
class MultifileClassPartCodegen(
|
||||||
v: ClassBuilder,
|
v: ClassBuilder,
|
||||||
@@ -162,25 +158,7 @@ class MultifileClassPartCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateKotlinMetadataAnnotation() {
|
override fun generateKotlinMetadataAnnotation() {
|
||||||
val members = ArrayList<DeclarationDescriptor>()
|
val (serializer, packageProto) = PackagePartCodegen.serializePackagePartMembers(this, partType)
|
||||||
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 extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
|
import kotlin.Pair;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
|
import kotlin.collections.CollectionsKt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||||
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
|
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.serialization.JvmSerializerExtension;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
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.Annotated;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
|
||||||
@@ -101,34 +100,42 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateKotlinMetadataAnnotation() {
|
protected void generateKotlinMetadataAnnotation() {
|
||||||
List<DeclarationDescriptor> members = new ArrayList<>();
|
Pair<DescriptorSerializer, ProtoBuf.Package> serializedPart = serializePackagePartMembers(this, packagePartType);
|
||||||
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();
|
|
||||||
|
|
||||||
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
|
||||||
writeAnnotationData(av, serializer, packageProto);
|
writeAnnotationData(av, serializedPart.getFirst(), serializedPart.getSecond());
|
||||||
return Unit.INSTANCE;
|
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
|
@Override
|
||||||
protected void generateSyntheticPartsAfterBody() {
|
protected void generateSyntheticPartsAfterBody() {
|
||||||
generateSyntheticAccessors();
|
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);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multifileClassWithTypealias.kt")
|
||||||
|
public void testMultifileClassWithTypealias() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/multifileClassWithTypealias.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nestedClass.kt")
|
@TestMetadata("nestedClass.kt")
|
||||||
public void testNestedClass() throws Exception {
|
public void testNestedClass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/nestedClass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/nestedClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user