diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 359a41f9517..5a5c9ad8615 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -86,7 +86,8 @@ public abstract class MemberCodegen ) { - private val header = "SMAP\n$source\nKotlin\n*S Kotlin" + private val header = "SMAP\n$source\nKotlin" fun build(): String? { - var realMappings = fileMappings.filter { + val realMappings = fileMappings.filter { val mappings = it.lineMappings mappings.isNotEmpty() && mappings.first() != RangeMapping.SKIP } @@ -41,10 +42,32 @@ class SMAPBuilder( return null } + val defaultStrata = generateDefaultStrata(realMappings) + val debugStrata = generateDebugStrata(realMappings) + + return "$header\n$defaultStrata$debugStrata" + } + + private fun generateDefaultStrata(realMappings: List): String { val fileIds = "*F" + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("") val lineMappings = "*L" + realMappings.joinToString("") { it.toSMAPMapping() } + return "*S Kotlin\n$fileIds\n$lineMappings\n*E\n" + } - return "$header\n$fileIds\n$lineMappings\n*E\n" + private fun generateDebugStrata(realMappings: List): String { + val combinedMapping = FileMapping(source, path) + realMappings.forEach { fileMapping -> + fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { rangeMapping -> + combinedMapping.addRangeMapping(RangeMapping(rangeMapping.callSiteMarker!!.lineNumber, rangeMapping.dest, rangeMapping.range)) + } + } + + if (combinedMapping.lineMappings.isEmpty()) return "" + + val newMappings = listOf(combinedMapping) + val fileIds = "*F" + newMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("") + val lineMappings = "*L" + newMappings.joinToString("") { it.toSMAPMapping() } + return "*S KotlinDebug\n$fileIds\n$lineMappings\n*E\n" } private fun RangeMapping.toSMAP(fileId: Int): String { @@ -145,9 +168,7 @@ interface SourceMapper { companion object { fun flushToClassBuilder(mapper: SourceMapper, v: ClassBuilder) { - for (fileMapping in mapper.resultMappings) { - v.addSMAP(fileMapping) - } + mapper.resultMappings.forEach { fileMapping -> v.addSMAP(fileMapping) } } fun createFromSmap(smap: SMAP): SourceMapper { @@ -333,7 +354,7 @@ open class FileMapping(val name: String, val path: String) { } //TODO comparable -data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) { +data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1, var callSiteMarker: CallSiteMarker? = null) { var parent: FileMapping? = null private val skip = source == -1 && dest == -1 @@ -370,3 +391,6 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) { val SKIP = RangeMapping(-1, -1, 1) } } + +val RangeMapping.toRange: IntRange + get() = this.dest..this.maxDest diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP2.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP2.kt index c3c50c97569..d0abae6ebc0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP2.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SMAP2.kt @@ -26,6 +26,9 @@ import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.MethodVisitor import java.util.* + +class CallSiteMarker(val lineNumber: Int) + open class NestedSourceMapper( override val parent: SourceMapper, val ranges: List, sourceInfo: SourceInfo ) : DefaultSourceMapper(sourceInfo) { @@ -86,6 +89,12 @@ open class DefaultSourceMapper @JvmOverloads constructor( protected var maxUsedValue: Int = sourceInfo.linesInFile ) : SourceMapper { + var callSiteMarker: CallSiteMarker? = null; + set(value) { + lastMappedWithChanges = null + field = value + } + var lastVisited: RawFileMapping? = null private var lastMappedWithChanges: RawFileMapping? = null private var fileMappings: LinkedHashMap = linkedMapOf() @@ -139,8 +148,7 @@ open class DefaultSourceMapper @JvmOverloads constructor( protected fun createMapping(lineNumber: Int): Int { val fileMapping = lastVisited!! - //val mappedLineIndex = fileMapping.mapLine(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited) - val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited) + val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited, callSiteMarker) if (mappedLineIndex > maxUsedValue) { lastMappedWithChanges = fileMapping maxUsedValue = mappedLineIndex @@ -167,7 +175,7 @@ class RawFileMapping(val name: String, val path: String) { lastMappedWithNewIndex = end } - fun mapNewLineNumber(source: Int, currentIndex: Int, isLastMapped: Boolean): Int { + fun mapNewLineNumber(source: Int, currentIndex: Int, isLastMapped: Boolean, callSiteMarker: CallSiteMarker?): Int { val dest: Int val rangeMapping: RangeMapping if (rangeMappings.isNotEmpty() && isLastMapped && couldFoldInRange(lastMappedWithNewIndex, source)) { @@ -177,7 +185,7 @@ class RawFileMapping(val name: String, val path: String) { } else { dest = currentIndex + 1 - rangeMapping = RangeMapping(source, dest) + rangeMapping = RangeMapping(source, dest, callSiteMarker = callSiteMarker) rangeMappings.add(rangeMapping) } diff --git a/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt b/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt index 572a10468bb..9889d57ca0b 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/codegen/SMAPTestUtil.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.output.OutputFile import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil import org.jetbrains.kotlin.codegen.inline.RangeMapping import org.jetbrains.kotlin.codegen.inline.SMAPParser +import org.jetbrains.kotlin.codegen.inline.toRange import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.org.objectweb.asm.ClassReader import org.jetbrains.org.objectweb.asm.ClassVisitor @@ -121,6 +122,3 @@ object SMAPTestUtil { } } } - -val RangeMapping.toRange: IntRange - get() = this.dest..this.maxDest