Skip smap generation if there is no source information
#KT-7022 Fixed
This commit is contained in:
@@ -35,12 +35,17 @@ public class SMAPBuilder(val source: String,
|
||||
val header = "SMAP\n$source\nKotlin\n*S Kotlin"
|
||||
|
||||
fun build(): String? {
|
||||
if (fileMappings.isEmpty()) {
|
||||
var realMappings = fileMappings.filter {
|
||||
val mappings = it.lineMappings
|
||||
mappings.isNotEmpty() && mappings.first() != RangeMapping.SKIP
|
||||
}
|
||||
|
||||
if (realMappings.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
val fileIds = "*F" + fileMappings.mapIndexed {(id, file) -> "\n${file.toSMAPFile(id + 1)}" }.join("")
|
||||
val lineMappings = "*L" + fileMappings.map { it.toSMAPMapping() }.join("")
|
||||
val fileIds = "*F" + realMappings.mapIndexed {(id, file) -> "\n${file.toSMAPFile(id + 1)}" }.join("")
|
||||
val lineMappings = "*L" + realMappings.map { it.toSMAPMapping() }.join("")
|
||||
|
||||
return "$header\n$fileIds\n$lineMappings\n*E\n"
|
||||
}
|
||||
@@ -212,6 +217,10 @@ public open class DefaultSourceMapper(val sourceInfo: SourceInfo, override val p
|
||||
}
|
||||
|
||||
override fun visitLineNumber(iv: MethodVisitor, lineNumber: Int, start: Label) {
|
||||
if (lineNumber < 0) {
|
||||
//no source information, so just skip this linenumber
|
||||
return
|
||||
}
|
||||
val mappedLineIndex = createMapping(lineNumber)
|
||||
iv.visitLineNumber(mappedLineIndex, start)
|
||||
}
|
||||
@@ -305,7 +314,7 @@ class RawFileMapping(val name: String, val path: String) {
|
||||
}
|
||||
}
|
||||
|
||||
public class FileMapping(val name: String, val path: String) {
|
||||
open public class FileMapping(val name: String, val path: String) {
|
||||
val lineMappings = arrayListOf<RangeMapping>()
|
||||
|
||||
var id = -1;
|
||||
@@ -314,18 +323,24 @@ public class FileMapping(val name: String, val path: String) {
|
||||
lineMappings.add(lineMapping)
|
||||
lineMapping.parent = this
|
||||
}
|
||||
|
||||
public object SKIP : FileMapping("no-source-info", "no-source-info") {
|
||||
init {
|
||||
addRangeMapping(RangeMapping.SKIP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO comparable
|
||||
data public class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
|
||||
data open public class RangeMapping(val source: Int, val dest: Int, var range: Int = 1) {
|
||||
|
||||
var parent: FileMapping? = null;
|
||||
|
||||
fun contains(destLine: Int): Boolean {
|
||||
open fun contains(destLine: Int): Boolean {
|
||||
return dest <= destLine && destLine < dest + range
|
||||
}
|
||||
|
||||
fun map(destLine: Int): Int {
|
||||
open fun map(destLine: Int): Int {
|
||||
return source + (destLine - dest)
|
||||
}
|
||||
|
||||
@@ -342,4 +357,15 @@ data public class RangeMapping(val source: Int, val dest: Int, var range: Int =
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public object SKIP : RangeMapping(-1, -1, 1) {
|
||||
override fun contains(destLine: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun map(destLine: Int): Int {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,17 +16,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.util.SmartFMap
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
object SMAPParser {
|
||||
|
||||
[platformStatic]
|
||||
public fun parseOrCreateDefault(mappingInfo: String?, source: String, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
|
||||
/*null smap means that there is no any debug info in file (e.g. sourceName)*/
|
||||
public fun parseOrCreateDefault(mappingInfo: String?, source: String?, path: String, methodStartLine: Int, methodEndLine: Int): SMAP {
|
||||
if (mappingInfo == null || mappingInfo.isEmpty()) {
|
||||
val fm = FileMapping(source, path)
|
||||
if (methodStartLine <= methodEndLine) {
|
||||
//one to one
|
||||
fm.addRangeMapping(RangeMapping(methodStartLine, methodStartLine, methodEndLine - methodStartLine + 1))
|
||||
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))
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package test
|
||||
|
||||
public class B {
|
||||
|
||||
public fun test(): String {
|
||||
var p = "fail"
|
||||
A().test {
|
||||
p = "OK"
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
public class A {
|
||||
|
||||
inline public fun test(s: () -> Unit) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+68
-4
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.jvm.compiler;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||
@@ -38,11 +39,12 @@ import org.jetbrains.kotlin.test.*;
|
||||
import org.jetbrains.kotlin.test.util.DescriptorValidator;
|
||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator;
|
||||
import org.jetbrains.kotlin.utils.UtilsPackage;
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
@@ -210,4 +212,66 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
|
||||
JetTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), output);
|
||||
}
|
||||
|
||||
/*test source mapping generation when source info is absent*/
|
||||
public void testInlineFunWithoutDebugInfo() throws Exception {
|
||||
File inlineSource = new File(getTestDataDirectory(), "sourceInline.kt");
|
||||
|
||||
CliBaseTest.executeCompilerGrabOutput(new K2JVMCompiler(), Arrays.asList(
|
||||
inlineSource.getPath(),
|
||||
"-d", tmpdir.getPath()
|
||||
));
|
||||
|
||||
File inlineFunClass = new File(tmpdir.getAbsolutePath(), "test/A.class");
|
||||
ClassReader reader = new ClassReader(new FileInputStream(inlineFunClass));
|
||||
ClassWriter cw = new ClassWriter(Opcodes.ASM5);
|
||||
reader.accept(new ClassVisitor(Opcodes.ASM5, cw) {
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
//skip debug info
|
||||
}
|
||||
}, 0);
|
||||
|
||||
assert inlineFunClass.delete();
|
||||
assert !inlineFunClass.exists();
|
||||
|
||||
FileOutputStream stream = new FileOutputStream(inlineFunClass);
|
||||
try {
|
||||
stream.write(cw.toByteArray());
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
}
|
||||
|
||||
File resultSource = new File(getTestDataDirectory(), "source.kt");
|
||||
CliBaseTest.executeCompilerGrabOutput(new K2JVMCompiler(), Arrays.asList(
|
||||
resultSource.getPath(),
|
||||
"-classpath", tmpdir.getPath(),
|
||||
"-d", tmpdir.getPath()
|
||||
));
|
||||
|
||||
File resultFile = new File(tmpdir.getAbsolutePath(), "test/B.class");
|
||||
reader = new ClassReader(new FileInputStream(resultFile));
|
||||
final Ref<String> debugInfo = new Ref<String>();
|
||||
reader.accept(new ClassVisitor(Opcodes.ASM5) {
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
//skip debug info
|
||||
debugInfo.set(debug);
|
||||
}
|
||||
}, 0);
|
||||
|
||||
String expected = "SMAP\n" +
|
||||
"source.kt\n" +
|
||||
"Kotlin\n" +
|
||||
"*S Kotlin\n" +
|
||||
"*F\n" +
|
||||
"+ 1 source.kt\n" +
|
||||
"test/B\n" +
|
||||
"*L\n" +
|
||||
"1#1,13:1\n" +
|
||||
"*E\n";
|
||||
|
||||
assertEquals(expected, debugInfo.get());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user