JVM: use precise line bounds when regenerating objects with no SMAPs
This commit is contained in:
+2
-1
@@ -117,7 +117,8 @@ class AnonymousObjectTransformer(
|
||||
// When regenerating objects in inline lambdas, keep the old SMAP and don't remap the line numbers to
|
||||
// save time. The result is effectively the same anyway.
|
||||
val debugInfoToParse = if (inliningContext.isInliningLambda) null else debugInfo
|
||||
sourceMap = SMAPParser.parseOrCreateDefault(debugInfoToParse, sourceInfo, oldObjectType.internalName, 1, 65535)
|
||||
val (firstLine, lastLine) = (methodsToTransform + listOfNotNull(constructor)).lineNumberRange()
|
||||
sourceMap = SMAPParser.parseOrCreateDefault(debugInfoToParse, sourceInfo, oldObjectType.internalName, firstLine, lastLine)
|
||||
sourceMapper = SourceMapper(sourceMap.fileMappings.firstOrNull { it.name == sourceInfo }?.toSourceInfo())
|
||||
|
||||
val allCapturedParamBuilder = ParametersBuilder.newBuilder()
|
||||
|
||||
@@ -92,12 +92,8 @@ internal fun getMethodNode(
|
||||
val cr = ClassReader(classData)
|
||||
var node: MethodNode? = null
|
||||
val debugInfo = arrayOfNulls<String>(2)
|
||||
val lines = IntArray(2)
|
||||
lines[0] = Integer.MAX_VALUE
|
||||
lines[1] = Integer.MIN_VALUE
|
||||
|
||||
cr.accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
||||
|
||||
override fun visitSource(source: String?, debug: String?) {
|
||||
super.visitSource(source, debug)
|
||||
debugInfo[0] = source
|
||||
@@ -123,16 +119,8 @@ internal fun getMethodNode(
|
||||
node?.let { existing ->
|
||||
throw AssertionError("Can't find proper '$name' method for inline: ambiguity between '${existing.name + existing.desc}' and '${name + desc}'")
|
||||
}
|
||||
|
||||
return object : MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions) {
|
||||
override fun visitLineNumber(line: Int, start: Label) {
|
||||
super.visitLineNumber(line, start)
|
||||
lines[0] = min(lines[0], line)
|
||||
lines[1] = max(lines[1], line)
|
||||
}
|
||||
}.also {
|
||||
node = it
|
||||
}
|
||||
node = MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions)
|
||||
return node!!
|
||||
}
|
||||
}, ClassReader.SKIP_FRAMES or if (GENERATE_SMAP) 0 else ClassReader.SKIP_DEBUG)
|
||||
|
||||
@@ -140,10 +128,25 @@ internal fun getMethodNode(
|
||||
return null
|
||||
}
|
||||
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classType.internalName, lines[0], lines[1])
|
||||
val (first, last) = listOfNotNull(node).lineNumberRange()
|
||||
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classType.internalName, first, last)
|
||||
return SMAPAndMethodNode(node!!, smap)
|
||||
}
|
||||
|
||||
internal fun Collection<MethodNode>.lineNumberRange(): Pair<Int, Int> {
|
||||
var minLine = Int.MAX_VALUE
|
||||
var maxLine = Int.MIN_VALUE
|
||||
for (node in this) {
|
||||
for (insn in node.instructions.asSequence()) {
|
||||
if (insn is LineNumberNode) {
|
||||
minLine = min(minLine, insn.line)
|
||||
maxLine = max(maxLine, insn.line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return minLine to maxLine
|
||||
}
|
||||
|
||||
internal fun findVirtualFile(state: GenerationState, classId: ClassId): VirtualFile? {
|
||||
return VirtualFileFinder.getInstance(state.project, state.module).findVirtualFileWithHeader(classId)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
run {
|
||||
object {
|
||||
init {
|
||||
result = "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 1 LINENUMBER 6
|
||||
@@ -3452,6 +3452,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/inlineCondition2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambdaObjectInit.kt")
|
||||
public void testInlineLambdaObjectInit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/inlineLambdaObjectInit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleThen.kt")
|
||||
public void testSingleThen() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/singleThen.kt");
|
||||
|
||||
+5
@@ -3537,6 +3537,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/inlineCondition2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambdaObjectInit.kt")
|
||||
public void testInlineLambdaObjectInit() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/inlineLambdaObjectInit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleThen.kt")
|
||||
public void testSingleThen() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/singleThen.kt");
|
||||
|
||||
Reference in New Issue
Block a user