Improve test data format for SMAP codegen tests

Instead of comments in a Kotlin source file, add a .smap with the contents of
the source mapping data (and possible comments)
This commit is contained in:
Alexander Udalov
2016-02-24 14:48:36 +03:00
committed by Alexander Udalov
parent cc84aabdcf
commit f7958edf21
19 changed files with 426 additions and 390 deletions
+43 -40
View File
@@ -8,22 +8,11 @@ inline fun call(crossinline init: () -> Unit) {
}() }()
} }
//SMAP
//lambda.2.kt
//Kotlin
//*S Kotlin
//*F
//+ 1 lambda.2.kt
//builders/Lambda_2Kt$call$1
//*L
//1#1,18:1
//*E
// FILE: 2.kt // FILE: 2.kt
import builders.* import builders.*
//NO_CHECK_LAMBDA_INLINING
fun test(): String { fun test(): String {
var res = "Fail" var res = "Fail"
@@ -38,32 +27,46 @@ fun test(): String {
fun box(): String { fun box(): String {
return test() return test()
} }
//NO_CHECK_LAMBDA_INLINING
//SMAP // FILE: 1.smap
//lambda.1.kt
//Kotlin SMAP
//*S Kotlin 1.kt
//*F Kotlin
//+ 1 lambda.1.kt *S Kotlin
//Lambda_1Kt *F
//+ 2 lambda.2.kt + 1 1.kt
//builders/Lambda_2Kt builders/_1Kt$call$1
//*L *L
//1#1,46:1 1#1,11:1
//4#2:47 *E
//*E
// // FILE: 2.smap
//SMAP
//lambda.2.kt SMAP
//Kotlin 2.kt
//*S Kotlin Kotlin
//*F *S Kotlin
//+ 1 lambda.2.kt *F
//builders/Lambda_2Kt$call$1 + 1 2.kt
//+ 2 lambda.1.kt _2Kt
//Lambda_1Kt + 2 1.kt
//*L builders/_1Kt
//1#1,18:1 *L
//8#2,2:19 1#1,21:1
//*E 6#2:22
*E
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
builders/_1Kt$call$1
+ 2 2.kt
_2Kt
*L
1#1,11:1
10#2,2:12
*E
@@ -6,7 +6,6 @@ inline fun call(crossinline init: () -> Unit) {
return init() return init()
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
@@ -30,17 +29,20 @@ fun box(): String {
return test() return test()
} }
// FILE: 1.smap
//SMAP // FILE: 2.smap
//lambdaOnCallSite.1.kt
//Kotlin SMAP
//*S Kotlin 2.kt
//*F Kotlin
//+ 1 lambdaOnCallSite.1.kt *S Kotlin
//LambdaOnCallSite_1Kt *F
//+ 2 lambdaOnCallSite.2.kt + 1 2.kt
//builders/LambdaOnCallSite_2Kt _2Kt
//*L + 2 1.kt
//1#1,34:1 builders/_1Kt
//4#2:35 *L
//*E 1#1,23:1
6#2:24
*E
@@ -6,8 +6,6 @@ inline fun call(crossinline init: () -> Unit) {
return init() return init()
} }
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import builders.* import builders.*
@@ -30,39 +28,44 @@ fun box(): String {
return test() return test()
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
// FILE: 1.smap
// FILE: 2.smap
//TODO SHOULD BE LESS //TODO SHOULD BE LESS
//SMAP SMAP
//lambdaOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 lambdaOnInlineCallSite.1.kt + 1 2.kt
//LambdaOnInlineCallSite_1Kt _2Kt
//+ 2 lambdaOnInlineCallSite.2.kt + 2 1.kt
//builders/LambdaOnInlineCallSite_2Kt builders/_1Kt
//*L *L
//1#1,56:1 1#1,24:1
//4#2:57 6#2:25
//*E *E
//
//SMAP SMAP
//lambdaOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 lambdaOnInlineCallSite.1.kt + 1 2.kt
//LambdaOnInlineCallSite_1Kt$test$1$1 _2Kt$test$1$1
//*L *L
//1#1,56:1 1#1,24:1
//*E *E
//
//SMAP SMAP
//lambdaOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 lambdaOnInlineCallSite.1.kt + 1 2.kt
//LambdaOnInlineCallSite_1Kt$test$1$1 _2Kt$test$1$1
//*L *L
//1#1,56:1 1#1,24:1
//*E *E
+43 -39
View File
@@ -10,18 +10,6 @@ inline fun call(crossinline init: () -> Unit) {
}.run() }.run()
} }
//SMAP
//object.2.kt
//Kotlin
//*S Kotlin
//*F
//+ 1 object.2.kt
//builders/Object_2Kt$call$1
//*L
//1#1,21:1
//*E
// FILE: 2.kt // FILE: 2.kt
import builders.* import builders.*
@@ -42,30 +30,46 @@ fun box(): String {
return test() return test()
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
//SMAP
//object.1.kt // FILE: 1.smap
//Kotlin
//*S Kotlin SMAP
//*F 1.kt
//+ 1 object.1.kt Kotlin
//Object_1Kt *S Kotlin
//+ 2 object.2.kt *F
//builders/Object_2Kt + 1 1.kt
//*L builders/_1Kt$call$1
//1#1,45:1 *L
//4#2,5:46 1#1,13:1
//*E *E
//
//SMAP // FILE: 2.smap
//object.2.kt
//Kotlin SMAP
//*S Kotlin 2.kt
//*F Kotlin
//+ 1 object.2.kt *S Kotlin
//builders/Object_2Kt$call$1 *F
//+ 2 object.1.kt + 1 2.kt
//Object_1Kt _2Kt
//*L + 2 1.kt
//1#1,21:1 builders/_1Kt
//8#2,2:22 *L
//*E 1#1,22:1
6#2,5:23
*E
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
builders/_1Kt$call$1
+ 2 2.kt
_2Kt
*L
1#1,13:1
10#2,2:14
*E
@@ -6,8 +6,6 @@ inline fun call(crossinline init: () -> Unit) {
return init() return init()
} }
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import builders.* import builders.*
@@ -33,16 +31,21 @@ fun box(): String {
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
// FILE: 1.smap
// FILE: 2.smap
//SMAP //SMAP
//objectOnCallSite.1.kt SMAP
//Kotlin 2.kt
//*S Kotlin Kotlin
//*F *S Kotlin
//+ 1 objectOnCallSite.1.kt *F
//ObjectOnCallSite_1Kt + 1 2.kt
//+ 2 objectOnCallSite.2.kt _2Kt
//builders/ObjectOnCallSite_2Kt + 2 1.kt
//*L builders/_1Kt
//1#1,36:1 *L
//4#2:37 1#1,26:1
//*E 6#2:27
*E
@@ -6,8 +6,6 @@ inline fun call(crossinline init: () -> Unit) {
return init() return init()
} }
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import builders.* import builders.*
@@ -32,39 +30,44 @@ fun box(): String {
return test() return test()
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
// FILE: 1.smap
// FILE: 2.smap
//TODO SHOULD BE LESS //TODO SHOULD BE LESS
//SMAP SMAP
//objectOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 objectOnInlineCallSite.1.kt + 1 2.kt
//ObjectOnInlineCallSite_1Kt _2Kt
//+ 2 objectOnInlineCallSite.2.kt + 2 1.kt
//builders/ObjectOnInlineCallSite_2Kt builders/_1Kt
//*L *L
//1#1,58:1 1#1,26:1
//4#2:59 6#2:27
//*E *E
//
//SMAP SMAP
//objectOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 objectOnInlineCallSite.1.kt + 1 2.kt
//ObjectOnInlineCallSite_1Kt$test$1$1 _2Kt$test$1$1
//*L *L
//1#1,58:1 1#1,26:1
//*E *E
//
//SMAP SMAP
//objectOnInlineCallSite.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 objectOnInlineCallSite.1.kt + 1 2.kt
//ObjectOnInlineCallSite_1Kt$test$1$1 _2Kt$test$1$1
//*L *L
//1#1,58:1 1#1,26:1
//*E *E
@@ -19,29 +19,6 @@ inline fun test(): String {
return res return res
} }
//TODO SHOULD BE LESS
//SXMAP
//objectOnInlineCallSite2.2.kt
//Kotlin
//*S Kotlin
//*F
//+ 1 objectOnInlineCallSite2.2.kt
//builders/BuildersPackage
//*L
//1#1,42:1
//*E
//
//SXMAP
//objectOnInlineCallSite2.2.kt
//Kotlin
//*S Kotlin
//*F
//+ 1 objectOnInlineCallSite2.2.kt
//builders/BuildersPackage$objectOnInlineCallSite2_2$HASH$test$1$1
//*L
//1#1,42:1
//*E
// FILE: 2.kt // FILE: 2.kt
@@ -53,27 +30,55 @@ fun box(): String {
} }
//NO_CHECK_LAMBDA_INLINING //NO_CHECK_LAMBDA_INLINING
//SXMAP // FILE: 1.sxmap
//objectOnInlineCallSite2.1.kt
//Kotlin //TODO SHOULD BE LESS
//*S Kotlin
//*F SXMAP
//+ 1 objectOnInlineCallSite2.1.kt objectOnInlineCallSite2.2.kt
//_DefaultPackage Kotlin
//+ 2 objectOnInlineCallSite2.2.kt *S Kotlin
//builders/BuildersPackage *F
//*L + 1 objectOnInlineCallSite2.2.kt
//1#1,32:1 builders/BuildersPackage
//8#2,11:33 *L
//*E 1#1,42:1
// *E
//SXMAP
//objectOnInlineCallSite2.2.kt SXMAP
//Kotlin objectOnInlineCallSite2.2.kt
//*S Kotlin Kotlin
//*F *S Kotlin
//+ 1 objectOnInlineCallSite2.2.kt *F
//builders/BuildersPackage$objectOnInlineCallSite2_2$HASH$test$1$1 + 1 objectOnInlineCallSite2.2.kt
//*L builders/BuildersPackage$objectOnInlineCallSite2_2$HASH$test$1$1
//1#1,42:1 *L
//*E 1#1,42:1
*E
// FILE: 2.sxmap
SXMAP
objectOnInlineCallSite2.1.kt
Kotlin
*S Kotlin
*F
+ 1 objectOnInlineCallSite2.1.kt
_DefaultPackage
+ 2 objectOnInlineCallSite2.2.kt
builders/BuildersPackage
*L
1#1,32:1
8#2,11:33
*E
SXMAP
objectOnInlineCallSite2.2.kt
Kotlin
*S Kotlin
*F
+ 1 objectOnInlineCallSite2.2.kt
builders/BuildersPackage$objectOnInlineCallSite2_2$HASH$test$1$1
*L
1#1,42:1
*E
+18 -16
View File
@@ -22,8 +22,6 @@ public inline fun massert(value: Boolean, message: Any = "Assertion failed") {
} }
} }
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import test.* import test.*
@@ -37,17 +35,21 @@ fun box(): String {
return "OK" return "OK"
} }
//SMAP // FILE: 1.smap
//assertion.1.kt
//Kotlin // FILE: 2.smap
//*S Kotlin
//*F SMAP
//+ 1 assertion.1.kt 2.kt
//Assertion_1Kt Kotlin
//+ 2 assertion.2.kt *S Kotlin
//test/Assertion_2Kt *F
//*L + 1 2.kt
//1#1,25:1 _2Kt
//15#2,7:26 + 2 1.kt
//6#2,7:33 test/_1Kt
//*E *L
1#1,14:1
17#2,7:15
8#2,7:22
*E
@@ -12,16 +12,18 @@ fun box(): String {
return "OK" return "OK"
} }
//SMAP // FILE: 2.smap
//classFromDefaultPackage.1.kt
//Kotlin SMAP
//*S Kotlin 2.kt
//*F Kotlin
//+ 1 classFromDefaultPackage.1.kt *S Kotlin
//ClassFromDefaultPackage_1Kt *F
//+ 2 classFromDefaultPackage.2.kt + 1 2.kt
//A _2Kt
//*L + 2 1.kt
//1#1,20:1 A
//2#2:21 *L
//*E 1#1,9:1
4#2:10
*E
+12 -10
View File
@@ -11,13 +11,15 @@ fun box(): String {
return "KO".reversed() return "KO".reversed()
} }
//SMAP // FILE: 2.smap
//noSmap.1.kt
//Kotlin SMAP
//*S Kotlin 2.kt
//*F Kotlin
//+ 1 noSmap.1.kt *S Kotlin
//NoSmap_1Kt *F
//*L + 1 2.kt
//1#1,14:1 _2Kt
//*E *L
1#1,7:1
*E
@@ -15,16 +15,18 @@ fun box(): String {
return "OK" return "OK"
} }
//SMAP // FILE: 2.smap
//reified.1.kt
//Kotlin SMAP
//*S Kotlin 2.kt
//*F Kotlin
//+ 1 reified.1.kt *S Kotlin
//Reified_1Kt *F
//+ 2 reified.2.kt + 1 2.kt
//test/Reified_2Kt _2Kt
//*L + 2 1.kt
//1#1,22:1 test/_1Kt
//3#2:23 *L
//*E 1#1,12:1
5#2:13
*E
+15 -12
View File
@@ -4,8 +4,6 @@ package zzz
inline fun nothing() {} inline fun nothing() {}
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
fun box(): String { fun box(): String {
@@ -19,14 +17,19 @@ inline fun test(p: () -> String): String {
pd = "O" pd = "O"
return pd + p() return pd + p()
} }
// FILE: 1.smap
// FILE: 2.smap
//TODO should be empty //TODO should be empty
//SMAP SMAP
//oneFile.1.kt 2.kt
//Kotlin Kotlin
//*S Kotlin *S Kotlin
//*F *F
//+ 1 oneFile.1.kt + 1 2.kt
//OneFile_1Kt _2Kt
//*L *L
//1#1,22:1 1#1,15:1
//*E *E
@@ -8,8 +8,6 @@ operator inline fun A.component1() = a
operator inline fun A.component2() = b operator inline fun A.component2() = b
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import zzz.* import zzz.*
@@ -20,16 +18,20 @@ fun box(): String {
return if (p == 1 && l == 11) "OK" else "fail: $p" return if (p == 1 && l == 11) "OK" else "fail: $p"
} }
//SMAP // FILE: 1.smap
//inlineComponent.1.kt
//Kotlin // FILE: 2.smap
//*S Kotlin
//*F SMAP
//+ 1 inlineComponent.1.kt 2.kt
//InlineComponent_1Kt Kotlin
//+ 2 inlineComponent.2.kt *S Kotlin
//zzz/InlineComponent_2Kt *F
//*L + 1 2.kt
//1#1,21:1 _2Kt
//5#2,3:22 + 2 1.kt
//*E zzz/_1Kt
*L
1#1,11:1
7#2,3:12
*E
@@ -6,8 +6,6 @@ public class A(val p: Int)
operator inline fun A.iterator() = (1..p).iterator() operator inline fun A.iterator() = (1..p).iterator()
//SMAP ABSENT
// FILE: 2.kt // FILE: 2.kt
import zzz.* import zzz.*
@@ -21,16 +19,20 @@ fun box(): String {
return if (p == 15) "OK" else "fail: $p" return if (p == 15) "OK" else "fail: $p"
} }
//SMAP // FILE: 1.smap
//inlineIterator.1.kt
//Kotlin // FILE: 2.smap
//*S Kotlin
//*F SMAP
//+ 1 inlineIterator.1.kt 2.kt
//InlineIterator_1Kt Kotlin
//+ 2 inlineIterator.2.kt *S Kotlin
//zzz/InlineIterator_2Kt *F
//*L + 1 2.kt
//1#1,24:1 _2Kt
//5#2:25 + 2 1.kt
//*E zzz/_1Kt
*L
1#1,14:1
7#2:15
*E
+32 -27
View File
@@ -17,17 +17,6 @@ inline fun head(init: () -> Unit) {val p = initTag2(init); return p}
inline fun html(init: () -> Unit) { inline fun html(init: () -> Unit) {
return init(init) return init(init)
} }
//TODO SHOULD BE EMPTY
//SMAP
//smap.2.kt
//Kotlin
//*S Kotlin
//*F
//+ 1 smap.2.kt
//builders/Smap_2Kt
//*L
//1#1,28:1
//*E
// FILE: 2.kt // FILE: 2.kt
@@ -53,19 +42,35 @@ fun box(): String {
return expected return expected
} }
//SMAP // FILE: 1.smap
//smap.1.kt
//Kotlin //TODO SHOULD BE EMPTY
//*S Kotlin SMAP
//*F 1.kt
//+ 1 smap.1.kt Kotlin
//Smap_1Kt *S Kotlin
//+ 2 smap.2.kt *F
//builders/Smap_2Kt + 1 1.kt
//*L builders/_1Kt
//1#1,38:1 *L
//16#2:39 1#1,21:1
//4#2,9:40 *E
//8#2,3:49
//5#2:52 // FILE: 2.smap
//*E
SMAP
2.kt
Kotlin
*S Kotlin
*F
+ 1 2.kt
_2Kt
+ 2 1.kt
builders/_1Kt
*L
1#1,25:1
18#2:26
6#2,9:27
10#2,3:36
7#2:39
*E
@@ -101,7 +101,9 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
List<KtFile> ktFiles = new ArrayList<KtFile>(files.size()); List<KtFile> ktFiles = new ArrayList<KtFile>(files.size());
for (TestFile file : files) { for (TestFile file : files) {
ktFiles.add(KotlinTestUtils.createFile(file.name, file.content, myEnvironment.getProject())); if (file.name.endsWith(".kt")) {
ktFiles.add(KotlinTestUtils.createFile(file.name, file.content, myEnvironment.getProject()));
}
} }
myFiles = CodegenTestFiles.create(ktFiles); myFiles = CodegenTestFiles.create(ktFiles);
@@ -34,7 +34,7 @@ abstract class AbstractBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest()
try { try {
InlineTestUtil.checkNoCallsToInline(initializedClassLoader.allGeneratedFiles.filterClassFiles(), myFiles.psiFiles) InlineTestUtil.checkNoCallsToInline(initializedClassLoader.allGeneratedFiles.filterClassFiles(), myFiles.psiFiles)
checkSMAP(myFiles.psiFiles, generateClassesInFile().getClassFiles()) checkSMAP(files, generateClassesInFile().getClassFiles())
} }
catch (e: Throwable) { catch (e: Throwable) {
System.out.println(generateToText()) System.out.println(generateToText())
@@ -27,13 +27,13 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCompileKot
override fun doMultiFileTest( override fun doMultiFileTest(
file: File, modules: Map<String, KotlinMultiFileTestWithJava<Void, TestFile>.ModuleAndDependencies>, files: List<TestFile> file: File, modules: Map<String, KotlinMultiFileTestWithJava<Void, TestFile>.ModuleAndDependencies>, files: List<TestFile>
) { ) {
assert(files.size == 2) { "There should be exactly two files in this test" } val kotlinFiles = files.filter { it.name.endsWith(".kt") }
assert(kotlinFiles.size == 2) { "There should be exactly two files in this test" }
var factory1: ClassFileFactory? = null var factory1: ClassFileFactory? = null
var factory2: ClassFileFactory? = null var factory2: ClassFileFactory? = null
try { try {
val fileA = files[0] val (fileA, fileB) = kotlinFiles
val fileB = files[1]
factory1 = compileA(fileA.name, fileA.content) factory1 = compileA(fileA.name, fileA.content)
factory2 = compileB(fileB.name, fileB.content) factory2 = compileB(fileB.name, fileB.content)
invokeBox(PackagePartClassUtils.getFilePartShortName(File(fileB.name).name)) invokeBox(PackagePartClassUtils.getFilePartShortName(File(fileB.name).name))
@@ -42,7 +42,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCompileKot
val sourceFiles = factory1.inputFiles + factory2.inputFiles val sourceFiles = factory1.inputFiles + factory2.inputFiles
InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), sourceFiles) InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), sourceFiles)
checkSMAP(sourceFiles, allGeneratedFiles.filterClassFiles()) checkSMAP(files, allGeneratedFiles.filterClassFiles())
} }
catch (e: Throwable) { catch (e: Throwable) {
var result = "" var result = ""
@@ -17,18 +17,18 @@
package org.jetbrains.kotlin.jvm.compiler package org.jetbrains.kotlin.jvm.compiler
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.backend.common.output.OutputFile import org.jetbrains.kotlin.backend.common.output.OutputFile
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.org.objectweb.asm.ClassReader import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.junit.Assert import org.junit.Assert
import java.io.File import java.io.File
import java.io.StringReader
interface AbstractSMAPBaseTest { interface AbstractSMAPBaseTest {
private fun extractSMAPFromClasses(outputFiles: Iterable<OutputFile>): List<SMAPAndFile> { private fun extractSMAPFromClasses(outputFiles: Iterable<OutputFile>): List<SMAPAndFile> {
return outputFiles.mapNotNull { outputFile -> return outputFiles.mapNotNull { outputFile ->
var debugInfo: String? = null var debugInfo: String? = null
@@ -42,52 +42,43 @@ interface AbstractSMAPBaseTest {
} }
} }
private fun extractSmapFromSource(file: KtFile): SMAPAndFile? { private fun extractSmapFromTestDataFile(file: CodegenTestCase.TestFile): SMAPAndFile? {
val fileContent = file.text if (!file.name.endsWith(".smap")) return null
val smapPrefix = "//SMAP"
if (InTextDirectivesUtils.isDirectiveDefined(fileContent, smapPrefix)) {
InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileContent, smapPrefix)
var smapData = fileContent.substring(fileContent.indexOf(smapPrefix))
smapData = smapData.replace("//", "").trim()
return SMAPAndFile(if (smapData.startsWith("SMAP ABSENT")) null else smapData, val content = buildString {
SMAPAndFile.getPath(file.virtualFile.canonicalPath!!)) StringReader(file.content).forEachLine { line ->
} // Strip comments
return null; if (!line.startsWith("//")) {
appendln(line.trim())
}
}
}.trim()
return SMAPAndFile(if (content.isNotEmpty()) content else null, SMAPAndFile.getPath(file.name))
} }
fun checkSMAP(inputFiles: List<KtFile>, outputFiles: Iterable<OutputFile>) { fun checkSMAP(inputFiles: List<CodegenTestCase.TestFile>, outputFiles: Iterable<OutputFile>) {
if (!InlineCodegenUtil.GENERATE_SMAP) { if (!InlineCodegenUtil.GENERATE_SMAP) return
return
}
val sourceData = inputFiles.mapNotNull { extractSmapFromSource(it) } val sourceData = inputFiles.mapNotNull { extractSmapFromTestDataFile(it) }
val compiledData = extractSMAPFromClasses(outputFiles).groupBy { val compiledData = extractSMAPFromClasses(outputFiles).groupBy {
it.sourceFile it.sourceFile
}.map { }.map {
val smap = it.value.mapNotNull { it.smap?.replaceHash() }.joinToString("\n") val smap = it.value.mapNotNull { it.smap }.joinToString("\n")
SMAPAndFile(if (smap.isNotEmpty()) smap else null, it.key) SMAPAndFile(if (smap.isNotEmpty()) smap else null, it.key)
}.associateBy { it.sourceFile } }.associateBy { it.sourceFile }
for (source in sourceData) { for (source in sourceData) {
val data = compiledData[source.sourceFile] val ktFileName = "/" + source.sourceFile.replace(".smap", ".kt")
Assert.assertEquals("Smap data differs for ${source.sourceFile}", source.smap, data?.smap?.trim()) val data = compiledData[ktFileName]
Assert.assertEquals("Smap data differs for $ktFileName", normalize(source.smap), normalize(data?.smap))
} }
} }
private fun normalize(text: String?) =
text?.let { StringUtil.convertLineSeparators(it.trim()) }
private fun String.replaceHash(): String { private class SMAPAndFile(val smap: String?, val sourceFile: String) {
val fileSectionStart = indexOf("*F") + 3
val lineSection = indexOf("*L") - 1
val files = substring(fileSectionStart, lineSection).split("\n")
val cleaned = files.joinToString("\n")
return substring(0, fileSectionStart) + cleaned + substring(lineSection)
}
class SMAPAndFile(val smap: String?, val sourceFile: String) {
companion object { companion object {
fun SMAPAndFile(smap: String?, sourceFile: File) = SMAPAndFile(smap, getPath(sourceFile)) fun SMAPAndFile(smap: String?, sourceFile: File) = SMAPAndFile(smap, getPath(sourceFile))