Minor, prettify Kotlin code in source maps
This commit is contained in:
@@ -24,11 +24,12 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import java.util.*
|
||||
|
||||
//TODO join parameter
|
||||
class SMAPBuilder(val source: String,
|
||||
val path: String,
|
||||
val fileMappings: List<FileMapping>) {
|
||||
|
||||
val header = "SMAP\n$source\nKotlin\n*S Kotlin"
|
||||
class SMAPBuilder(
|
||||
val source: String,
|
||||
val path: String,
|
||||
val fileMappings: List<FileMapping>
|
||||
) {
|
||||
private val header = "SMAP\n$source\nKotlin\n*S Kotlin"
|
||||
|
||||
fun build(): String? {
|
||||
var realMappings = fileMappings.filter {
|
||||
@@ -37,7 +38,7 @@ class SMAPBuilder(val source: String,
|
||||
}
|
||||
|
||||
if (realMappings.isEmpty()) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
val fileIds = "*F" + realMappings.mapIndexed { id, file -> "\n${file.toSMAPFile(id + 1)}" }.joinToString("")
|
||||
@@ -46,29 +47,29 @@ class SMAPBuilder(val source: String,
|
||||
return "$header\n$fileIds\n$lineMappings\n*E\n"
|
||||
}
|
||||
|
||||
|
||||
fun RangeMapping.toSMAP(fileId: Int): String {
|
||||
private fun RangeMapping.toSMAP(fileId: Int): String {
|
||||
return if (range == 1) "$source#$fileId:$dest" else "$source#$fileId,$range:$dest"
|
||||
}
|
||||
|
||||
fun FileMapping.toSMAPFile(id: Int): String {
|
||||
this.id = id;
|
||||
private fun FileMapping.toSMAPFile(id: Int): String {
|
||||
this.id = id
|
||||
return "+ $id $name\n$path"
|
||||
}
|
||||
|
||||
//TODO inline
|
||||
fun FileMapping.toSMAPMapping(): String {
|
||||
private fun FileMapping.toSMAPMapping(): String {
|
||||
return lineMappings.joinToString("") { "\n${it.toSMAP(id)}" }
|
||||
}
|
||||
}
|
||||
|
||||
open class NestedSourceMapper(parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo) : DefaultSourceMapper(sourceInfo, parent) {
|
||||
|
||||
open class NestedSourceMapper(
|
||||
parent: SourceMapper, val ranges: List<RangeMapping>, sourceInfo: SourceInfo
|
||||
) : DefaultSourceMapper(sourceInfo, parent) {
|
||||
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
|
||||
val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) {
|
||||
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
|
||||
value, key ->
|
||||
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
}
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
if (index < 0) {
|
||||
parent!!.visitSource(sourceInfo.source, sourceInfo.pathOrCleanFQN)
|
||||
parent!!.visitLineNumber(iv, lineNumber, start)
|
||||
@@ -81,8 +82,9 @@ open class NestedSourceMapper(parent: SourceMapper, val ranges: List<RangeMappin
|
||||
}
|
||||
}
|
||||
|
||||
open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNode) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) {
|
||||
|
||||
open class InlineLambdaSourceMapper(
|
||||
parent: SourceMapper, smap: SMAPAndMethodNode
|
||||
) : NestedSourceMapper(parent, smap.ranges, smap.classSMAP.sourceInfo) {
|
||||
override fun visitSource(name: String, path: String) {
|
||||
super.visitSource(name, path)
|
||||
if (isOriginalVisited()) {
|
||||
@@ -100,13 +102,13 @@ open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNod
|
||||
}
|
||||
|
||||
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
|
||||
val index = Collections.binarySearch(ranges, RangeMapping(lineNumber, lineNumber, 1)) {
|
||||
val index = ranges.binarySearch(RangeMapping(lineNumber, lineNumber, 1), Comparator {
|
||||
value, key ->
|
||||
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
}
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
if (index >= 0) {
|
||||
val fmapping = ranges[index].parent!!
|
||||
if (fmapping.path == origin.path && fmapping.name == origin.name) {
|
||||
val mapping = ranges[index].parent!!
|
||||
if (mapping.path == origin.path && mapping.name == origin.name) {
|
||||
parent!!.visitOrigin()
|
||||
parent!!.visitLineNumber(iv, lineNumber, start)
|
||||
return
|
||||
@@ -117,7 +119,6 @@ open class InlineLambdaSourceMapper(parent: SourceMapper, smap: SMAPAndMethodNod
|
||||
}
|
||||
|
||||
interface SourceMapper {
|
||||
|
||||
val resultMappings: List<FileMapping>
|
||||
val parent: SourceMapper?
|
||||
|
||||
@@ -138,7 +139,6 @@ interface SourceMapper {
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun flushToClassBuilder(mapper: SourceMapper, v: ClassBuilder) {
|
||||
for (fileMapping in mapper.resultMappings) {
|
||||
v.addSMAP(fileMapping)
|
||||
@@ -179,15 +179,10 @@ object IdenticalSourceMapper : SourceMapper {
|
||||
}
|
||||
|
||||
open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent: SourceMapper?): SourceMapper {
|
||||
|
||||
protected var maxUsedValue: Int = sourceInfo.linesInFile
|
||||
|
||||
var lastVisited: RawFileMapping? = null
|
||||
|
||||
private var lastMappedWithChanges: RawFileMapping? = null
|
||||
|
||||
var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
|
||||
|
||||
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
|
||||
protected val origin: RawFileMapping
|
||||
|
||||
init {
|
||||
@@ -205,7 +200,7 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent:
|
||||
get() = fileMappings.values.map { it.toFileMapping() }
|
||||
|
||||
override fun visitSource(name: String, path: String) {
|
||||
lastVisited = fileMappings.getOrPut(createKey(name, path), { RawFileMapping(name, path) })
|
||||
lastVisited = fileMappings.getOrPut(createKey(name, path)) { RawFileMapping(name, path) }
|
||||
}
|
||||
|
||||
override fun visitOrigin() {
|
||||
@@ -232,7 +227,6 @@ open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val parent:
|
||||
}
|
||||
}
|
||||
|
||||
/*Source Mapping*/
|
||||
class SMAP(val fileMappings: List<FileMapping>) {
|
||||
init {
|
||||
assert(fileMappings.isNotEmpty()) { "File Mappings shouldn't be empty" }
|
||||
@@ -251,9 +245,7 @@ class SMAP(val fileMappings: List<FileMapping>) {
|
||||
|
||||
companion object {
|
||||
val FILE_SECTION = "*F"
|
||||
|
||||
val LINE_SECTION = "*L"
|
||||
|
||||
val END = "*E"
|
||||
}
|
||||
}
|
||||
@@ -262,15 +254,14 @@ class RawFileMapping(val name: String, val path: String) {
|
||||
private val lineMappings = TIntIntHashMap()
|
||||
private val rangeMappings = arrayListOf<RangeMapping>()
|
||||
|
||||
private var lastMappedWithNewIndex = -1000;
|
||||
private var lastMappedWithNewIndex = -1000
|
||||
|
||||
fun toFileMapping(): FileMapping {
|
||||
val fileMapping = FileMapping(name, path)
|
||||
for (range in rangeMappings) {
|
||||
fileMapping.addRangeMapping(range)
|
||||
}
|
||||
return fileMapping
|
||||
}
|
||||
fun toFileMapping() =
|
||||
FileMapping(name, path).apply {
|
||||
for (range in rangeMappings) {
|
||||
addRangeMapping(range)
|
||||
}
|
||||
}
|
||||
|
||||
fun initRange(start: Int, end: Int) {
|
||||
assert(lineMappings.isEmpty) { "initRange should only be called for empty mapping" }
|
||||
@@ -315,14 +306,13 @@ class RawFileMapping(val name: String, val path: String) {
|
||||
private fun couldFoldInRange(first: Int, second: Int): Boolean {
|
||||
//TODO
|
||||
val delta = second - first
|
||||
return delta > 0 && delta <= 10;
|
||||
return delta > 0 && delta <= 10
|
||||
}
|
||||
}
|
||||
|
||||
open class FileMapping(val name: String, val path: String) {
|
||||
val lineMappings = arrayListOf<RangeMapping>()
|
||||
|
||||
var id = -1;
|
||||
var id = -1
|
||||
|
||||
fun addRangeMapping(lineMapping: RangeMapping) {
|
||||
lineMappings.add(lineMapping)
|
||||
@@ -338,12 +328,10 @@ open class FileMapping(val name: String, val path: String) {
|
||||
|
||||
//TODO comparable
|
||||
data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
|
||||
|
||||
var parent: FileMapping? = null;
|
||||
|
||||
var parent: FileMapping? = null
|
||||
private val skip = source == -1 && dest == -1
|
||||
|
||||
fun contains(destLine: Int): Boolean {
|
||||
operator fun contains(destLine: Int): Boolean {
|
||||
return if (skip) true else dest <= destLine && destLine < dest + range
|
||||
}
|
||||
|
||||
@@ -368,4 +356,4 @@ data class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
|
||||
companion object {
|
||||
val SKIP = RangeMapping(-1, -1, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,30 +16,26 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||
import org.jetbrains.org.objectweb.asm.tree.LineNumberNode
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import kotlin.properties.Delegates
|
||||
import java.util.Collections
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import org.jetbrains.kotlin.codegen.SourceInfo
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
|
||||
//TODO comment
|
||||
class SMAPAndMethodNode(val node: MethodNode, val classSMAP: SMAP) {
|
||||
|
||||
val lineNumbers =
|
||||
InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map {
|
||||
val index = Collections.binarySearch(classSMAP.intervals, RangeMapping(it.line, it.line, 1)) {
|
||||
private val lineNumbers =
|
||||
InsnSequence(node.instructions.first, null).filterIsInstance<LineNumberNode>().map { node ->
|
||||
val index = classSMAP.intervals.binarySearch(RangeMapping(node.line, node.line, 1), Comparator {
|
||||
value, key ->
|
||||
if (value.contains(key.dest)) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
if (key.dest in value) 0 else RangeMapping.Comparator.compare(value, key)
|
||||
})
|
||||
if (index < 0) {
|
||||
error("Unmapped label in inlined function $node ${node.line}")
|
||||
}
|
||||
if (index < 0)
|
||||
throw IllegalStateException("Unmapped label in inlined function $it ${it.line}")
|
||||
LabelAndMapping(it, classSMAP.intervals[index])
|
||||
LabelAndMapping(node, classSMAP.intervals[index])
|
||||
}.toList()
|
||||
|
||||
val ranges = lineNumbers.asSequence().map { it.mapper }.distinct().toList();
|
||||
val ranges = lineNumbers.asSequence().map { it.mapper }.distinct().toList()
|
||||
}
|
||||
|
||||
class LabelAndMapping(val lineNumberNode: LineNumberNode, val mapper: RangeMapping)
|
||||
class LabelAndMapping(val lineNumberNode: LineNumberNode, val mapper: RangeMapping)
|
||||
|
||||
@@ -16,51 +16,49 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.util.SmartFMap
|
||||
|
||||
object SMAPParser {
|
||||
|
||||
/*null smap means that there is no any debug info in file (e.g. sourceName)*/
|
||||
@JvmStatic
|
||||
/*null smap means that there is no any debug info in file (e.g. sourceName)*/ fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
|
||||
if (mappingInfo == null || mappingInfo.isEmpty()) {
|
||||
val fm: FileMapping
|
||||
if (source == null || source.isEmpty()) {
|
||||
fm = FileMapping.SKIP
|
||||
}
|
||||
else {
|
||||
fm = FileMapping(source, path)
|
||||
if (methodStartLine <= methodEndLine) {
|
||||
//one to one
|
||||
fm.addRangeMapping(RangeMapping(methodStartLine, methodStartLine, methodEndLine - methodStartLine + 1))
|
||||
}
|
||||
}
|
||||
return SMAP(listOf(fm))
|
||||
fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
|
||||
if (mappingInfo != null && mappingInfo.isNotEmpty()) {
|
||||
return parse(mappingInfo)
|
||||
}
|
||||
return parse(mappingInfo)
|
||||
|
||||
val mapping =
|
||||
if (source == null || source.isEmpty())
|
||||
FileMapping.SKIP
|
||||
else
|
||||
FileMapping(source, path).apply {
|
||||
if (methodStartLine <= methodEndLine) {
|
||||
//one to one
|
||||
addRangeMapping(RangeMapping(methodStartLine, methodStartLine, methodEndLine - methodStartLine + 1))
|
||||
}
|
||||
}
|
||||
|
||||
return SMAP(listOf(mapping))
|
||||
}
|
||||
|
||||
@JvmStatic fun parse(mappingInfo: String): SMAP {
|
||||
@JvmStatic
|
||||
fun parse(mappingInfo: String): SMAP {
|
||||
val fileMappings = linkedMapOf<Int, FileMapping>()
|
||||
|
||||
val fileSectionStart = mappingInfo.indexOf(SMAP.FILE_SECTION) + SMAP.FILE_SECTION.length
|
||||
val lineSectionAnchor = mappingInfo.indexOf(SMAP.LINE_SECTION)
|
||||
val files = mappingInfo.substring(fileSectionStart, lineSectionAnchor)
|
||||
|
||||
|
||||
val fileEntries = files.trim().split('+')
|
||||
|
||||
for (fileDeclaration in fileEntries) {
|
||||
if (fileDeclaration == "") continue;
|
||||
if (fileDeclaration == "") continue
|
||||
val fileInternalName = fileDeclaration.trim()
|
||||
|
||||
val indexEnd = fileInternalName.indexOf(' ')
|
||||
val fileIndex = Integer.valueOf(fileInternalName.substring(0, indexEnd))
|
||||
val fileIndex = fileInternalName.substring(0, indexEnd).toInt()
|
||||
val newLine = fileInternalName.indexOf('\n')
|
||||
val fileName = fileInternalName.substring(indexEnd + 1, newLine)
|
||||
fileMappings.put(fileIndex, FileMapping(fileName, fileInternalName.substring(newLine + 1).trim()))
|
||||
fileMappings[fileIndex] = FileMapping(fileName, fileInternalName.substring(newLine + 1).trim())
|
||||
}
|
||||
|
||||
|
||||
val lines = mappingInfo.substring(lineSectionAnchor + SMAP.LINE_SECTION.length, mappingInfo.indexOf(SMAP.END)).trim().split('\n')
|
||||
for (lineMapping in lines) {
|
||||
/*only simple mapping now*/
|
||||
@@ -69,14 +67,14 @@ object SMAPParser {
|
||||
var rangeSeparator = originalPart.indexOf(',').let { if (it < 0) targetSplit else it }
|
||||
|
||||
val fileSeparator = lineMapping.indexOf('#')
|
||||
val originalIndex = Integer.valueOf(originalPart.substring(0, fileSeparator))
|
||||
val range = if (rangeSeparator == targetSplit) 1 else Integer.valueOf(originalPart.substring(rangeSeparator + 1, targetSplit))
|
||||
val originalIndex = originalPart.substring(0, fileSeparator).toInt()
|
||||
val range = if (rangeSeparator == targetSplit) 1 else originalPart.substring(rangeSeparator + 1, targetSplit).toInt()
|
||||
|
||||
val fileIndex = Integer.valueOf(lineMapping.substring(fileSeparator + 1, rangeSeparator))
|
||||
val targetIndex = Integer.valueOf(lineMapping.substring(targetSplit + 1))
|
||||
val fileIndex = lineMapping.substring(fileSeparator + 1, rangeSeparator).toInt()
|
||||
val targetIndex = lineMapping.substring(targetSplit + 1).toInt()
|
||||
fileMappings[fileIndex]!!.addRangeMapping(RangeMapping(originalIndex, targetIndex, range))
|
||||
}
|
||||
|
||||
return SMAP(fileMappings.values.toList())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user