SourceMappers refactoring

This commit is contained in:
Michael Bogdanov
2016-04-20 12:44:48 +03:00
parent bb5c24eae5
commit c70e1c6065
@@ -143,24 +143,16 @@ interface SourceMapper {
val parent: SourceMapper? val parent: SourceMapper?
get() = null get() = null
open fun visitSource(name: String, path: String) { fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
throw UnsupportedOperationException("fail") throw UnsupportedOperationException("fail")
} }
open fun visitOrigin() { fun visitLineNumber(iv: MethodVisitor, start: Label, source: Int, sourceName: String, sourcePath:String): Int {
throw UnsupportedOperationException("fail") throw UnsupportedOperationException("fail")
} }
open fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) { fun endMapping() {
throw UnsupportedOperationException("fail")
}
open fun visitLineNumber(iv: MethodVisitor, start: Label, source: Int, sourceName: String, sourcePath:String): Int {
throw UnsupportedOperationException("fail")
}
open fun endMapping() {
parent?.visitOrigin()
} }
companion object { companion object {
@@ -169,19 +161,7 @@ interface SourceMapper {
} }
fun createFromSmap(smap: SMAP): SourceMapper { fun createFromSmap(smap: SMAP): SourceMapper {
val maxUsedIndex = smap.fileMappings.maxBy { it.lineMappings.maxBy { it.maxDest }!!.maxDest }!!.lineMappings.maxBy { it.maxDest }!!.maxDest return DefaultSourceMapper(smap.sourceInfo, smap.fileMappings)
val sourceMapper = DefaultSourceMapper(smap.sourceInfo, maxUsedIndex)
smap.fileMappings.asSequence()
//default one mapped through sourceInfo
.filterNot { it == smap.default }
.forEach { fileMapping ->
sourceMapper.visitSource(fileMapping.name, fileMapping.path)
fileMapping.lineMappings.forEach {
sourceMapper.lastVisited!!.mapNewInterval(it.source, it.dest, it.range)
}
}
return sourceMapper
} }
} }
} }
@@ -193,10 +173,6 @@ object IdenticalSourceMapper : SourceMapper {
override val parent: SourceMapper? override val parent: SourceMapper?
get() = null get() = null
override fun visitSource(name: String, path: String) {}
override fun visitOrigin() {}
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) { override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
iv.visitLineNumber(lineNumber, start) iv.visitLineNumber(lineNumber, start)
} }
@@ -204,10 +180,15 @@ object IdenticalSourceMapper : SourceMapper {
class CallSiteMarker(val lineNumber: Int) class CallSiteMarker(val lineNumber: Int)
open class DefaultSourceMapper @JvmOverloads constructor( open class DefaultSourceMapper(val sourceInfo: SourceInfo) : SourceMapper {
val sourceInfo: SourceInfo,
protected var maxUsedValue: Int = sourceInfo.linesInFile private var maxUsedValue: Int = sourceInfo.linesInFile
) : SourceMapper {
private var lastMappedWithChanges: RawFileMapping? = null
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
protected val origin: RawFileMapping
var callSiteMarker: CallSiteMarker? = null; var callSiteMarker: CallSiteMarker? = null;
set(value) { set(value) {
@@ -215,10 +196,9 @@ open class DefaultSourceMapper @JvmOverloads constructor(
field = value field = value
} }
var lastVisited: RawFileMapping? = null override val resultMappings: List<FileMapping>
private var lastMappedWithChanges: RawFileMapping? = null get() = fileMappings.values.map { it.toFileMapping() }
private var fileMappings: LinkedHashMap<String, RawFileMapping> = linkedMapOf()
protected val origin: RawFileMapping
init { init {
val name = sourceInfo.source val name = sourceInfo.source
@@ -226,20 +206,24 @@ open class DefaultSourceMapper @JvmOverloads constructor(
origin = RawFileMapping(name, path) origin = RawFileMapping(name, path)
origin.initRange(1, sourceInfo.linesInFile) origin.initRange(1, sourceInfo.linesInFile)
fileMappings.put(createKey(name, path), origin) fileMappings.put(createKey(name, path), origin)
lastVisited = origin }
constructor(sourceInfo: SourceInfo, fileMappings: List<FileMapping>): this(sourceInfo) {
fileMappings.asSequence().drop(1)
//default one mapped through sourceInfo
.forEach { fileMapping ->
val newFileMapping = getOrRegisterNewSource(fileMapping.name, fileMapping.path)
fileMapping.lineMappings.forEach {
newFileMapping.mapNewInterval(it.source, it.dest, it.range)
maxUsedValue = Math.max(it.maxDest, maxUsedValue)
}
}
} }
private fun createKey(name: String, path: String) = "$name#$path" private fun createKey(name: String, path: String) = "$name#$path"
override val resultMappings: List<FileMapping> private fun getOrRegisterNewSource(name: String, path: String): RawFileMapping {
get() = fileMappings.values.map { it.toFileMapping() } return fileMappings.getOrPut(createKey(name, path)) { RawFileMapping(name, path) }
override fun visitSource(name: String, path: String) {
lastVisited = fileMappings.getOrPut(createKey(name, path)) { RawFileMapping(name, path) }
}
override fun visitOrigin() {
lastVisited = origin
} }
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) { override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
@@ -247,10 +231,6 @@ open class DefaultSourceMapper @JvmOverloads constructor(
//no source information, so just skip this linenumber //no source information, so just skip this linenumber
return return
} }
//TODO add assertion that mapping exists
//val sourceLineNumber = createMapping(lineNumberToMap)
val sourceLineNumber = lineNumber
assert(lineNumber == sourceLineNumber)
iv.visitLineNumber(lineNumber, start) iv.visitLineNumber(lineNumber, start)
} }
@@ -259,16 +239,13 @@ open class DefaultSourceMapper @JvmOverloads constructor(
//no source information, so just skip this linenumber //no source information, so just skip this linenumber
return -1 return -1
} }
visitSource(sourceName, sourcePath) val mappedLineIndex = createMapping(getOrRegisterNewSource(sourceName, sourcePath), source)
val mappedLineIndex = createMapping(source)
iv.visitLineNumber(mappedLineIndex, start) iv.visitLineNumber(mappedLineIndex, start)
return mappedLineIndex return mappedLineIndex
} }
protected fun createMapping(lineNumber: Int): Int { private fun createMapping(fileMapping: RawFileMapping, lineNumber: Int): Int {
val fileMapping = lastVisited!! val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == fileMapping, callSiteMarker)
val mappedLineIndex = fileMapping.mapNewLineNumber(lineNumber, maxUsedValue, lastMappedWithChanges == lastVisited, callSiteMarker)
if (mappedLineIndex > maxUsedValue) { if (mappedLineIndex > maxUsedValue) {
lastMappedWithChanges = fileMapping lastMappedWithChanges = fileMapping
maxUsedValue = mappedLineIndex maxUsedValue = mappedLineIndex