JVM_IR: fix source file name for mutlifile class facades
This commit is contained in:
@@ -726,7 +726,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
public SourceMapper getOrCreateSourceMapper() {
|
||||
if (sourceMapper == null) {
|
||||
// note: this is used in InlineCodegen and the element is always physical (KtElement) there
|
||||
sourceMapper = new SourceMapper(SourceInfo.Companion.createInfo((KtElement)element, getClassName()));
|
||||
sourceMapper = new SourceMapper(SourceInfo.Companion.createFromPsi((KtElement)element, getClassName()));
|
||||
}
|
||||
return sourceMapper;
|
||||
}
|
||||
|
||||
@@ -21,28 +21,26 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
|
||||
data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesInFile: Int) {
|
||||
data class SourceInfo(
|
||||
val sourceFileName: String?,
|
||||
val pathOrCleanFQN: String,
|
||||
val linesInFile: Int
|
||||
) {
|
||||
|
||||
companion object {
|
||||
fun createInfo(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
fun createFromPsi(element: KtElement?, internalClassName: String): SourceInfo {
|
||||
assert(element != null) { "Couldn't create source mapper for null element $internalClassName" }
|
||||
val lineNumbers = CodegenUtil.getLineNumberForElement(element!!.containingFile, true)
|
||||
?: error("Couldn't extract line count in ${element.containingFile}")
|
||||
?: error("Couldn't extract line count in ${element.containingFile}")
|
||||
|
||||
//TODO hack condition for package parts cleaning
|
||||
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
|
||||
|
||||
return SourceInfo(element.containingKtFile.name, cleanedClassFqName, lineNumbers)
|
||||
val fileName = element.containingKtFile.name
|
||||
return SourceInfo(fileName, cleanedClassFqName, lineNumbers)
|
||||
}
|
||||
|
||||
fun createInfoForIr(lineNumbers: Int, internalClassName: String, containingFileName: String): SourceInfo {
|
||||
//TODO cut topLevel names
|
||||
// val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
|
||||
// val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
|
||||
|
||||
return SourceInfo(containingFileName, internalClassName, lineNumbers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -28,10 +27,8 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
@@ -233,7 +230,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
)
|
||||
|
||||
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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -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()
|
||||
|
||||
+9
-5
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+12
@@ -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() {}
|
||||
+17
@@ -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
|
||||
}
|
||||
+19
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MultiFileClass")
|
||||
|
||||
fun foo() {}
|
||||
@@ -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
|
||||
}
|
||||
+12
@@ -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
|
||||
}
|
||||
+10
@@ -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");
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user