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
|
// 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.
|
// save time. The result is effectively the same anyway.
|
||||||
val debugInfoToParse = if (inliningContext.isInliningLambda) null else debugInfo
|
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())
|
sourceMapper = SourceMapper(sourceMap.fileMappings.firstOrNull { it.name == sourceInfo }?.toSourceInfo())
|
||||||
|
|
||||||
val allCapturedParamBuilder = ParametersBuilder.newBuilder()
|
val allCapturedParamBuilder = ParametersBuilder.newBuilder()
|
||||||
|
|||||||
@@ -92,12 +92,8 @@ internal fun getMethodNode(
|
|||||||
val cr = ClassReader(classData)
|
val cr = ClassReader(classData)
|
||||||
var node: MethodNode? = null
|
var node: MethodNode? = null
|
||||||
val debugInfo = arrayOfNulls<String>(2)
|
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) {
|
cr.accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
||||||
|
|
||||||
override fun visitSource(source: String?, debug: String?) {
|
override fun visitSource(source: String?, debug: String?) {
|
||||||
super.visitSource(source, debug)
|
super.visitSource(source, debug)
|
||||||
debugInfo[0] = source
|
debugInfo[0] = source
|
||||||
@@ -123,16 +119,8 @@ internal fun getMethodNode(
|
|||||||
node?.let { existing ->
|
node?.let { existing ->
|
||||||
throw AssertionError("Can't find proper '$name' method for inline: ambiguity between '${existing.name + existing.desc}' and '${name + desc}'")
|
throw AssertionError("Can't find proper '$name' method for inline: ambiguity between '${existing.name + existing.desc}' and '${name + desc}'")
|
||||||
}
|
}
|
||||||
|
node = MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions)
|
||||||
return object : MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions) {
|
return node!!
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, ClassReader.SKIP_FRAMES or if (GENERATE_SMAP) 0 else ClassReader.SKIP_DEBUG)
|
}, ClassReader.SKIP_FRAMES or if (GENERATE_SMAP) 0 else ClassReader.SKIP_DEBUG)
|
||||||
|
|
||||||
@@ -140,10 +128,25 @@ internal fun getMethodNode(
|
|||||||
return null
|
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)
|
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? {
|
internal fun findVirtualFile(state: GenerationState, classId: ClassId): VirtualFile? {
|
||||||
return VirtualFileFinder.getInstance(state.project, state.module).findVirtualFileWithHeader(classId)
|
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");
|
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")
|
@TestMetadata("singleThen.kt")
|
||||||
public void testSingleThen() throws Exception {
|
public void testSingleThen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/singleThen.kt");
|
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");
|
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")
|
@TestMetadata("singleThen.kt")
|
||||||
public void testSingleThen() throws Exception {
|
public void testSingleThen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/singleThen.kt");
|
runTest("compiler/testData/codegen/bytecodeText/lineNumbers/singleThen.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user