diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index f7fc95bec09..df22baa40ae 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -726,7 +726,7 @@ public abstract class MemberCodegen( ) val sourceInfo = sourceMapper.sourceInfo!! - val callSite = SourcePosition(codegen.lastLineNumber, sourceInfo.source, sourceInfo.pathOrCleanFQN) + val callSite = SourcePosition(codegen.lastLineNumber, sourceInfo.sourceFileName!!, sourceInfo.pathOrCleanFQN) val inliner = MethodInliner( node, parameters, info, FieldRemapper(null, null, parameters), isSameModule, "Method inlining " + sourceCompiler.callElementText, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt index cc02cb9bbca..d5cb052a383 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP.kt @@ -85,9 +85,14 @@ class SourceMapper(val sourceInfo: SourceInfo?) { get() = fileMappings.values.toList() init { - sourceInfo?.let { - // Explicitly map the file to itself -- we'll probably need a lot of lines from it, so this will produce fewer ranges. - getOrRegisterNewSource(it.source, it.pathOrCleanFQN).mapNewInterval(1, 1, it.linesInFile) + sourceInfo?.let { sourceInfo -> + // If 'sourceFileName' is null, this class doesn't have debug information + // (e.g., multi-file class facade with multiple parts). + sourceInfo.sourceFileName?.let { sourceFileName -> + // Explicitly map the file to itself -- we'll probably need a lot of lines from it, so this will produce fewer ranges. + getOrRegisterNewSource(sourceFileName, sourceInfo.pathOrCleanFQN) + .mapNewInterval(1, 1, sourceInfo.linesInFile) + } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 919e109f090..41cc01eb992 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -153,7 +153,9 @@ abstract class ClassCodegen protected constructor( if (withinInline || !smap.isTrivial) { visitor.visitSMAP(smap, !context.state.languageVersionSettings.supportsFeature(LanguageFeature.CorrectSourceMappingSyntax)) } else { - visitor.visitSource(smap.sourceInfo!!.source, null) + smap.sourceInfo!!.sourceFileName?.let { + visitor.visitSource(it, null) + } } visitor.done() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index 6a72dd8a34f..dfd9bbe63ac 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -87,15 +87,19 @@ fun JvmBackendContext.getSourceMapper(declaration: IrClass): SourceMapper { // NOTE: apparently inliner requires the source range to cover the // whole file the class is declared in rather than the class only. // TODO: revise - val endLineNumber = when { - fileEntry is MultifileFacadeFileEntry -> 0 + val endLineNumber = when (fileEntry) { + is MultifileFacadeFileEntry -> 0 else -> fileEntry?.getSourceRangeInfo(0, fileEntry.maxOffset)?.endLineNumber ?: 0 } + val sourceFileName = when (fileEntry) { + is MultifileFacadeFileEntry -> fileEntry.partFiles.singleOrNull()?.name + else -> declaration.fileParent.name + } return SourceMapper( - SourceInfo.createInfoForIr( - endLineNumber + 1, + SourceInfo( + sourceFileName, typeMapper.mapClass(declaration).internalName, - declaration.fileParent.name + endLineNumber + 1 ) ) } diff --git a/compiler/testData/codegen/bytecodeListing/main/multifileSuspend_ir.txt b/compiler/testData/codegen/bytecodeListing/main/multifileSuspend_ir.txt index 04c75ee4846..551f2ab4f61 100644 --- a/compiler/testData/codegen/bytecodeListing/main/multifileSuspend_ir.txt +++ b/compiler/testData/codegen/bytecodeListing/main/multifileSuspend_ir.txt @@ -1,6 +1,6 @@ @kotlin.Metadata public final class Hello/Foo { - // source: 'Foo>' + // source: 'multifileSuspend.kt' public final static method main(@org.jetbrains.annotations.NotNull p0: java.lang.String[]): void public final static @org.jetbrains.annotations.Nullable method main(@org.jetbrains.annotations.NotNull p0: java.lang.String[], @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object } diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.kt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.kt new file mode 100644 index 00000000000..a80cb928886 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// FILE: part1.kt +@file:JvmMultifileClass +@file:JvmName("MultiFileClass") + +fun foo() {} + +// FILE: part2.kt +@file:JvmMultifileClass +@file:JvmName("MultiFileClass") + +fun bar() {} diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.txt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.txt new file mode 100644 index 00000000000..775a99b4921 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.txt @@ -0,0 +1,17 @@ +@kotlin.Metadata +public final class MultiFileClass { + public final static method bar(): void + public final static method foo(): void +} + +@kotlin.Metadata +synthetic final class MultiFileClass__Part1Kt { + // source: 'part1.kt' + public final static method foo(): void +} + +@kotlin.Metadata +synthetic final class MultiFileClass__Part2Kt { + // source: 'part2.kt' + public final static method bar(): void +} diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts_ir.txt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts_ir.txt new file mode 100644 index 00000000000..5a106aadbd9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts_ir.txt @@ -0,0 +1,19 @@ +@kotlin.Metadata +public final class MultiFileClass { + public final static method bar(): void + public final static method foo(): void +} + +@kotlin.Metadata +@kotlin.jvm.JvmName +synthetic final class MultiFileClass__Part1Kt { + // source: 'part1.kt' + public final static method foo(): void +} + +@kotlin.Metadata +@kotlin.jvm.JvmName +synthetic final class MultiFileClass__Part2Kt { + // source: 'part2.kt' + public final static method bar(): void +} diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.kt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.kt new file mode 100644 index 00000000000..c19d27dfd0e --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.kt @@ -0,0 +1,5 @@ +// WITH_RUNTIME +@file:JvmMultifileClass +@file:JvmName("MultiFileClass") + +fun foo() {} diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.txt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.txt new file mode 100644 index 00000000000..ebae4a67163 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.txt @@ -0,0 +1,11 @@ +@kotlin.Metadata +public final class MultiFileClass { + // source: 'multiClassPartSourceSinglePart.kt' + public final static method foo(): void +} + +@kotlin.Metadata +synthetic final class MultiFileClass__MultiClassPartSourceSinglePartKt { + // source: 'multiClassPartSourceSinglePart.kt' + public final static method foo(): void +} diff --git a/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart_ir.txt b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart_ir.txt new file mode 100644 index 00000000000..174b419f18e --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart_ir.txt @@ -0,0 +1,12 @@ +@kotlin.Metadata +public final class MultiFileClass { + // source: 'multiClassPartSourceSinglePart.kt' + public final static method foo(): void +} + +@kotlin.Metadata +@kotlin.jvm.JvmName +synthetic final class MultiFileClass__MultiClassPartSourceSinglePartKt { + // source: 'multiClassPartSourceSinglePart.kt' + public final static method foo(): void +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 68fe1383b1b..20aa9adf411 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -104,6 +104,16 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); } + @TestMetadata("multiClassPartSourceMultipleParts.kt") + public void testMultiClassPartSourceMultipleParts() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.kt"); + } + + @TestMetadata("multiClassPartSourceSinglePart.kt") + public void testMultiClassPartSourceSinglePart() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 7d8a0824c57..f51a98240d6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -104,6 +104,16 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); } + @TestMetadata("multiClassPartSourceMultipleParts.kt") + public void testMultiClassPartSourceMultipleParts() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/multiClassPartSourceMultipleParts.kt"); + } + + @TestMetadata("multiClassPartSourceSinglePart.kt") + public void testMultiClassPartSourceSinglePart() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/multiClassPartSourceSinglePart.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt");