From cd341e957e63e1eb7eddfad302a214c174f615f8 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 9 Sep 2015 15:12:12 +0300 Subject: [PATCH] Cleanup after review + stub builder test for multifile class --- .../kotlin/codegen/MultifileClassCodegen.kt | 49 ++------ .../jvm/diagnostics/JvmDeclarationOrigin.kt | 12 +- .../psi/stubs/impl/KotlinFileStubImpl.kt | 17 ++- ...eadKotlinClassHeaderAnnotationVisitor.java | 1 - .../jvm/internal/KotlinMultifileClass.java | 1 - .../kotlin/idea/decompiler/DecompiledUtils.kt | 16 +-- .../stubBuilder/KotlinClsStubBuilder.kt | 21 +--- .../decompiler/stubBuilder/clsStubBuilding.kt | 8 +- .../textBuilder/DecompiledTextFactory.kt | 8 -- .../MultifileClass.expected.kt | 16 ++- .../MultifileClass/MultifileClass.kt | 7 +- .../MultifileClass/andSomeMore.kt | 6 +- .../MultifileClass/MultifileClass.kt | 10 ++ .../MultifileClass/MultifileClass.txt | 113 ++++++++++++++++++ .../stubBuilder/MultifileClass/SecondPart.kt | 7 ++ .../ClsStubBuilderTestGenerated.java | 6 + 16 files changed, 202 insertions(+), 96 deletions(-) create mode 100644 idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.kt create mode 100644 idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.txt create mode 100644 idea/testData/decompiler/stubBuilder/MultifileClass/SecondPart.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt index bf8d7dac344..534f53b80cc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt @@ -65,36 +65,32 @@ public class MultifileClassCodegen( // We can do this (probably without 'compiledPackageFragment') after modifications to part codegen. private val classBuilder = ClassBuilderOnDemand { - val filesWithTopLevelCallables = files.filter { hasTopLevelCallables(it) } - val sourceFile = filesWithTopLevelCallables.firstOrNull() + val originFile = files.firstOrNull() val actualPackageFragment = packageFragment ?: compiledPackageFragment ?: throw AssertionError("No package fragment for multifile facade $facadeFqName; files: $files") - val declarationOrigin = MultifileClass(sourceFile, actualPackageFragment, facadeFqName) - val classBuilder = state.factory.newVisitor(declarationOrigin, facadeClassType, filesWithTopLevelCallables) + val declarationOrigin = MultifileClass(originFile, actualPackageFragment, facadeFqName) + val classBuilder = state.factory.newVisitor(declarationOrigin, facadeClassType, files) - classBuilder.defineClass(sourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES, + val filesWithCallables = files.filter { it.declarations.any { it is JetNamedFunction || it is JetProperty } } + val singleSourceFile = filesWithCallables.singleOrNull() + classBuilder.defineClass(singleSourceFile, Opcodes.V1_6, FACADE_CLASS_ATTRIBUTES, facadeClassType.internalName, null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY) - sourceFile?.let { classBuilder.visitSource(it.name, null) } + if (singleSourceFile != null) { + classBuilder.visitSource(singleSourceFile.name, null) + } classBuilder } - private fun hasTopLevelCallables(file: JetFile) = - file.declarations.any { it is JetNamedFunction || it is JetProperty } - public fun generate(errorHandler: CompilationErrorHandler) { - val bindings = ArrayList(files.size() + 1) val generateCallableMemberTasks = HashMap Unit>() val partFqNames = arrayListOf() for (file in files) { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() try { - val partClassBuilder = generatePart(file, generateCallableMemberTasks, partFqNames) - if (partClassBuilder != null) { - bindings.add(partClassBuilder.serializationBindings) - } + generatePart(file, generateCallableMemberTasks, partFqNames) } catch (e: ProcessCanceledException) { throw e @@ -113,13 +109,12 @@ public class MultifileClassCodegen( // generateDelegationsToPreviouslyCompiled(generateCallableMemberTasks) if (!generateCallableMemberTasks.isEmpty()) { - generateMultifileFacadeClass(generateCallableMemberTasks, bindings, partFqNames) + generateMultifileFacadeClass(generateCallableMemberTasks, partFqNames) } } private fun generateMultifileFacadeClass( tasks: Map Unit>, - bindings: MutableList, partFqNames: List ) { MemberCodegen.generateModuleNameField(state, classBuilder) @@ -128,8 +123,7 @@ public class MultifileClassCodegen( tasks[member]!!() } - bindings.add(classBuilder.serializationBindings) - writeKotlinMultifileFacadeAnnotationIfNeeded(JvmSerializationBindings.union(bindings), partFqNames) + writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames) } public fun generateClassOrObject(classOrObject: JetClassOrObject) { @@ -196,21 +190,10 @@ public class MultifileClassCodegen( return builder } - private fun writeKotlinMultifileFacadeAnnotationIfNeeded(bindings: JvmSerializationBindings, partFqNames: List) { + private fun writeKotlinMultifileFacadeAnnotationIfNeeded(partFqNames: List) { if (state.classBuilderMode != ClassBuilderMode.FULL) return if (files.any { it.isScript }) return - val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(bindings, state.typeMapper)) - - val packageFragments = arrayListOf() - ContainerUtil.addIfNotNull(packageFragments, packageFragment) - ContainerUtil.addIfNotNull(packageFragments, compiledPackageFragment) - val facadeProto = serializer.packageProto(packageFragments, /* skip= */ { true }).build() - - val strings = serializer.stringTable - val nameResolver = NameResolver(strings.serializeSimpleNames(), strings.serializeQualifiedNames()) - val facadeData = PackageData(nameResolver, facadeProto) - val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true) av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION) @@ -221,12 +204,6 @@ public class MultifileClassCodegen( } filePartClassNamesArray.visitEnd() - val dataArray = av.visitArray(JvmAnnotationNames.DATA_FIELD_NAME) - for (string in BitEncoding.encodeBytes(SerializationUtil.serializePackageData(facadeData))) { - dataArray.visit(null, string) - } - dataArray.visitEnd() - av.visitEnd() } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt index be7051fb694..1305da475c2 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt @@ -48,8 +48,7 @@ public enum class JvmDeclarationOriginKind { public class JvmDeclarationOrigin( public val originKind: JvmDeclarationOriginKind, public val element: PsiElement?, - public val descriptor: DeclarationDescriptor?, - public val multifileClassFqName: FqName? = null + public val descriptor: DeclarationDescriptor? ) { companion object { public val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, null) @@ -71,10 +70,13 @@ public fun Bridge(descriptor: DeclarationDescriptor, element: PsiElement? = Desc public fun PackageFacade(descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(PACKAGE_FACADE, null, descriptor) public fun PackagePart(file: JetFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(PACKAGE_PART, file, descriptor) -public fun MultifileClass(someFile: JetFile?, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin = - JvmDeclarationOrigin(MULTIFILE_CLASS, someFile, descriptor, multifileClassFqName) +/** + * @param representativeFile one of the files representing this multifile class (will be used for diagnostics) + */ +public fun MultifileClass(representativeFile: JetFile?, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin = + JvmDeclarationOrigin(MULTIFILE_CLASS, representativeFile, descriptor) public fun MultifileClassPart(file: JetFile, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin = - JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor, multifileClassFqName) + JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor) public fun TraitImpl(element: JetClassOrObject, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(TRAIT_IMPL, element, descriptor) public fun DelegationToTraitImpl(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt index e88073d76b7..ad4880de75c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt @@ -23,6 +23,7 @@ import com.intellij.psi.stubs.PsiFileStubImpl import com.intellij.psi.tree.IStubFileElementType import com.intellij.util.io.StringRef import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.stubs.KotlinFileStub import org.jetbrains.kotlin.psi.stubs.KotlinImportDirectiveStub @@ -67,9 +68,19 @@ public class KotlinFileStubImpl( public fun forFileFacadeStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = KotlinFileStubImpl(jetFile = null, - packageName = StringRef.fromString(facadeFqName.parent().asString())!!, - facadeSimpleName = StringRef.fromString(facadeFqName.shortName().asString())!!, - partSimpleName = StringRef.fromString(facadeFqName.shortName().asString())!!, + packageName = facadeFqName.parent().stringRef(), + facadeSimpleName = facadeFqName.shortName().stringRef(), + partSimpleName = facadeFqName.shortName().stringRef(), isScript = isScript) + + public fun forMultifileClassStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = + KotlinFileStubImpl(jetFile = null, + packageName = facadeFqName.parent().stringRef(), + facadeSimpleName = facadeFqName.shortName().stringRef(), + partSimpleName = null, + isScript = isScript) + + private fun FqName.stringRef() = StringRef.fromString(asString())!! + private fun Name.stringRef() = StringRef.fromString(asString())!! } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java index e7944135830..e6f83989d13 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/header/ReadKotlinClassHeaderAnnotationVisitor.java @@ -95,7 +95,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor return headerKind == CLASS || headerKind == PACKAGE_FACADE || headerKind == FILE_FACADE || - headerKind == MULTIFILE_CLASS || headerKind == MULTIFILE_CLASS_PART; } diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/KotlinMultifileClass.java b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinMultifileClass.java index 095b2d0a3d0..616e34f0932 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/KotlinMultifileClass.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/KotlinMultifileClass.java @@ -24,5 +24,4 @@ public @interface KotlinMultifileClass { int abiVersion(); String[] filePartClassNames(); - String[] data(); } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt index 39c0f30159e..1e6ce14cafb 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/DecompiledUtils.kt @@ -89,10 +89,7 @@ public object HasCompiledKotlinInJar : JarUserDataManager.JarBooleanPropertyCoun JarUserDataManager.hasFileWithProperty(HasCompiledKotlinInJar, file) == false } -public class ReadMultifileClassException(message: String): RuntimeException(message) - public fun findMultifileClassParts(file: VirtualFile, multifileClass: KotlinJvmBinaryClass): List { - val result = arrayListOf() val packageFqName = multifileClass.classId.packageFqName val partsFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName) val partNames = multifileClass.classHeader.filePartClassNames ?: return emptyList() @@ -101,14 +98,5 @@ public fun findMultifileClassParts(file: VirtualFile, multifileClass: KotlinJvmB }.filterNotNull() } -@Throws(ReadMultifileClassException::class) -public fun readMultifileClassPartHeaders(file: VirtualFile, multifileClass: KotlinJvmBinaryClass): List { - val classId = multifileClass.classId - val classHeader = multifileClass.classHeader - if (classHeader.filePartClassNames == null) { - throw ReadMultifileClassException("Multifile class $classId has no filePartClassNames or wrong ABI version: ${classHeader.version}") - } - else { - return findMultifileClassParts(file, multifileClass).map { it.classHeader } - } -} +public fun readMultifileClassPartHeaders(file: VirtualFile, multifileClass: KotlinJvmBinaryClass): List = + findMultifileClassParts(file, multifileClass).map { it.classHeader } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt index 2cb64cd6c9c..2e205bc17b9 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/KotlinClsStubBuilder.kt @@ -22,7 +22,6 @@ import com.intellij.psi.compiled.ClsStubBuilder import com.intellij.psi.impl.compiled.ClassFileStubBuilder import com.intellij.psi.stubs.PsiFileStub import com.intellij.util.indexing.FileContent -import org.jetbrains.kotlin.idea.decompiler.ReadMultifileClassException import org.jetbrains.kotlin.idea.decompiler.isKotlinInternalCompiledFile import org.jetbrains.kotlin.idea.decompiler.readMultifileClassPartHeaders import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedClassFinder @@ -30,10 +29,11 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedDataFinder import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache -import org.jetbrains.kotlin.load.kotlin.header.* -import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassKind +import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil @@ -83,17 +83,8 @@ public open class KotlinClsStubBuilder : ClsStubBuilder() { createFileFacadeStub(packageData.getPackageProto(), classId.asSingleFqName(), context) } header.isCompatibleMultifileClassKind() -> { - val packageData = JvmProtoBufUtil.readPackageDataFrom(annotationData) - val context = components.createContext(packageData.nameResolver, packageFqName) - val partHeaders = - try { - readMultifileClassPartHeaders(file, kotlinBinaryClass) - } - catch (e: ReadMultifileClassException) { - LOG.error(e.getMessage()) - return null - } - createMultifileClassStub(partHeaders, classId.asSingleFqName(), context) + val partHeaders = readMultifileClassPartHeaders(file, kotlinBinaryClass) + createMultifileClassStub(partHeaders, classId.asSingleFqName(), components) } else -> throw IllegalStateException("Should have processed " + file.getPath() + " with header $header") } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt index df9751bdb25..cbd191ee32c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt @@ -75,15 +75,15 @@ fun createFileFacadeStub( fun createMultifileClassStub( partHeaders: List, facadeFqName: FqName, - c: ClsStubBuilderContext + components: ClsStubBuilderComponents ): KotlinFileStubImpl { val packageFqName = facadeFqName.parent() - val fileStub = KotlinFileStubImpl.forFileFacadeStub(facadeFqName, packageFqName.isRoot) + val fileStub = KotlinFileStubImpl.forMultifileClassStub(facadeFqName, packageFqName.isRoot) setupFileStub(fileStub, packageFqName) - val multifileClassContainer = ProtoContainer(null, facadeFqName.parent()) + val multifileClassContainer = ProtoContainer(null, packageFqName) for (partHeader in partHeaders) { val partData = JvmProtoBufUtil.readPackageDataFrom(partHeader.annotationData!!) - val partContext = c.child(partData.nameResolver) + val partContext = components.createContext(partData.nameResolver, packageFqName) for (partMember in partData.packageProto.memberList) { createCallableStub(fileStub, partMember, partContext, multifileClassContainer) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextFactory.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextFactory.kt index d67b7438119..f26df58541c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextFactory.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/textBuilder/DecompiledTextFactory.kt @@ -19,10 +19,8 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder import com.intellij.openapi.util.TextRange import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.idea.decompiler.ReadMultifileClassException import org.jetbrains.kotlin.idea.decompiler.findMultifileClassParts import org.jetbrains.kotlin.idea.decompiler.navigation.JsMetaFileUtils -import org.jetbrains.kotlin.idea.decompiler.readMultifileClassPartHeaders import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache import org.jetbrains.kotlin.load.kotlin.PackageClassUtils @@ -51,12 +49,6 @@ public val INCOMPATIBLE_ABI_VERSION_COMMENT: String = "// Current compiler ABI version is $CURRENT_ABI_VERSION_MARKER\n" + "// File ABI version is $FILE_ABI_VERSION_MARKER" -private val REASON = "REASON" -public val FILE_CANT_BE_DECOMPILED_DUE_TO_ERRORS: String = - "// This class file has inconsistent Kotlin meta-information and can't be decompiled.\n" + - "//\n" + - "// $REASON" - public fun buildDecompiledText( classFile: VirtualFile, resolver: ResolverForDecompiler = DeserializerForDecompiler(classFile) diff --git a/idea/testData/decompiler/decompiledTextJvm/MultifileClass.expected.kt b/idea/testData/decompiler/decompiledTextJvm/MultifileClass.expected.kt index 314d33793f9..ffda79591fc 100644 --- a/idea/testData/decompiler/decompiledTextJvm/MultifileClass.expected.kt +++ b/idea/testData/decompiler/decompiledTextJvm/MultifileClass.expected.kt @@ -3,10 +3,18 @@ package test -public val p: kotlin.Int /* compiled code */ +public val val1b: kotlin.Int /* compiled code */ -public fun f(): kotlin.Unit { /* compiled code */ } +private val kotlin.String.val2b: kotlin.Int /* compiled code */ -private var i: kotlin.Int /* compiled code */ +public fun fn1b(): kotlin.Unit { /* compiled code */ } -public fun kotlin.Int.plus(i: kotlin.Int /* = compiled code */): kotlin.Int { /* compiled code */ } \ No newline at end of file +public fun kotlin.String.fn2b(): kotlin.Unit { /* compiled code */ } + +public val val1a: kotlin.Int /* compiled code */ + +private val kotlin.String.val2a: kotlin.Int /* compiled code */ + +public fun fn1a(): kotlin.Unit { /* compiled code */ } + +public fun kotlin.String.fn2a(): kotlin.Unit { /* compiled code */ } \ No newline at end of file diff --git a/idea/testData/decompiler/decompiledTextJvm/MultifileClass/MultifileClass.kt b/idea/testData/decompiler/decompiledTextJvm/MultifileClass/MultifileClass.kt index ac7a21c0fd0..f11fd9d7726 100644 --- a/idea/testData/decompiler/decompiledTextJvm/MultifileClass/MultifileClass.kt +++ b/idea/testData/decompiler/decompiledTextJvm/MultifileClass/MultifileClass.kt @@ -2,9 +2,10 @@ @file:JvmMultifileClass package test -private var i = 2 - -fun Int.plus(i: Int = 1) = this + i +public val val1a = 42 +private val String.val2a: Int get() = 0 +public fun fn1a() {} +public fun String.fn2a() {} class ShouldNotBeVisible1 interface ShouldNotBeVisible2 diff --git a/idea/testData/decompiler/decompiledTextJvm/MultifileClass/andSomeMore.kt b/idea/testData/decompiler/decompiledTextJvm/MultifileClass/andSomeMore.kt index 8b77dc6586a..a5119cb52c0 100644 --- a/idea/testData/decompiler/decompiledTextJvm/MultifileClass/andSomeMore.kt +++ b/idea/testData/decompiler/decompiledTextJvm/MultifileClass/andSomeMore.kt @@ -2,5 +2,7 @@ @file:JvmMultifileClass package test -fun f() {} -val p = 3 \ No newline at end of file +public val val1b = 42 +private val String.val2b: Int get() = 0 +public fun fn1b() {} +public fun String.fn2b() {} diff --git a/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.kt b/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.kt new file mode 100644 index 00000000000..9cf18d88079 --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.kt @@ -0,0 +1,10 @@ +@file:[JvmName("MultifileClass") JvmMultifileClass] +package test + +fun p1Fun() {} +fun String.p1ExtFun() {} +fun p1ExprFun(): Int = 0 +fun p1FunWithParams(x: Int): Int { return x } +val p1Val: Int = 0 +val String.p1ExtVal: Int get() = 0 +var p1Var: Int = 0 \ No newline at end of file diff --git a/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.txt b/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.txt new file mode 100644 index 00000000000..a239ae68a8a --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/MultifileClass/MultifileClass.txt @@ -0,0 +1,113 @@ +PsiJetFileStubImpl[package=test] + PACKAGE_DIRECTIVE: + REFERENCE_EXPRESSION:[referencedName=test] + IMPORT_LIST: + PROPERTY:[fqName=test.p1Val, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=false, name=p1Val] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + PROPERTY:[fqName=test.p1Var, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=true, name=p1Var] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + PROPERTY:[fqName=test.p1ExtVal, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=true, isTopLevel=true, isVar=false, name=p1ExtVal] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=String] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + FUN:[fqName=test.p1ExprFun, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=p1ExprFun] + MODIFIER_LIST:[public] + VALUE_PARAMETER_LIST: + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + FUN:[fqName=test.p1Fun, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=p1Fun] + MODIFIER_LIST:[public] + VALUE_PARAMETER_LIST: + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Unit] + FUN:[fqName=test.p1FunWithParams, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=p1FunWithParams] + MODIFIER_LIST:[public] + VALUE_PARAMETER_LIST: + VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=x] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + FUN:[fqName=test.p1ExtFun, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=true, isTopLevel=true, name=p1ExtFun] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=String] + VALUE_PARAMETER_LIST: + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Unit] + PROPERTY:[fqName=test.p2Val, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=false, name=p2Val] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + PROPERTY:[fqName=test.p2ExtVal, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=true, isTopLevel=true, isVar=false, name=p2ExtVal] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=String] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Int] + FUN:[fqName=test.p2Fun, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=p2Fun] + MODIFIER_LIST:[public] + VALUE_PARAMETER_LIST: + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Unit] + FUN:[fqName=test.p2ExtFun, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=true, isTopLevel=true, name=p2ExtFun] + MODIFIER_LIST:[public] + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=String] + VALUE_PARAMETER_LIST: + TYPE_REFERENCE: + USER_TYPE:[isAbsoluteInRootPackage=false] + USER_TYPE:[isAbsoluteInRootPackage=false] + REFERENCE_EXPRESSION:[referencedName=kotlin] + REFERENCE_EXPRESSION:[referencedName=Unit] diff --git a/idea/testData/decompiler/stubBuilder/MultifileClass/SecondPart.kt b/idea/testData/decompiler/stubBuilder/MultifileClass/SecondPart.kt new file mode 100644 index 00000000000..98afe03f826 --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/MultifileClass/SecondPart.kt @@ -0,0 +1,7 @@ +@file:[JvmName("MultifileClass") JvmMultifileClass] +package test + +fun p2Fun() {} +fun String.p2ExtFun() {} +val p2Val: Int = 0 +val String.p2ExtVal: Int get() = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java index 43b939e3394..d1aa5f8d7bf 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java @@ -107,6 +107,12 @@ public class ClsStubBuilderTestGenerated extends AbstractClsStubBuilderTest { doTest(fileName); } + @TestMetadata("MultifileClass") + public void testMultifileClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/MultifileClass/"); + doTest(fileName); + } + @TestMetadata("NestedClasses") public void testNestedClasses() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/NestedClasses/");