Working infrastructure for external dependencies testing
(not really, but at least something)
This commit is contained in:
@@ -18,15 +18,19 @@ package org.jetbrains.kotlin.ir
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
import java.io.File
|
||||
@@ -42,9 +46,36 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
|
||||
for ((testFile, irFile) in ktFiles.zip(irModule.files)) {
|
||||
doTestIrFileAgainstExpectations(dir, testFile, irFile)
|
||||
}
|
||||
|
||||
doTestIrModuleDependencies(wholeFile, irModule)
|
||||
}
|
||||
|
||||
protected fun doTestIrFileAgainstExpectations(dir: File, testFile: TestFile, irFile: IrFile) {
|
||||
private fun doTestIrModuleDependencies(wholeFile: File, irModule: IrModuleFragment) {
|
||||
val wholeText = wholeFile.readText()
|
||||
|
||||
val stubGenerator = DeclarationStubGenerator(
|
||||
irModule.descriptor,
|
||||
SymbolTable(), // TODO
|
||||
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
|
||||
myEnvironment.configuration.languageVersionSettings
|
||||
)
|
||||
|
||||
for (externalClassFqn in parseDumpExternalClasses(wholeText)) {
|
||||
val classDump = stubGenerator.generateExternalClass(irModule.descriptor, externalClassFqn).dump()
|
||||
val expectedFile = File(wholeFile.path.replace(".kt", "__$externalClassFqn.txt"))
|
||||
KotlinTestUtils.assertEqualsToFile(expectedFile, classDump)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DeclarationStubGenerator.generateExternalClass(descriptor: ModuleDescriptor, externalClassFqn: String): IrClass {
|
||||
val classDescriptor =
|
||||
descriptor.findClassAcrossModuleDependencies(ClassId.topLevel(FqName(externalClassFqn)))
|
||||
?: throw AssertionError("Can't find a class in external dependencies: $externalClassFqn")
|
||||
|
||||
return generateMemberStub(classDescriptor) as IrClass
|
||||
}
|
||||
|
||||
private fun doTestIrFileAgainstExpectations(dir: File, testFile: TestFile, irFile: IrFile) {
|
||||
if (testFile.isExternalFile()) return
|
||||
|
||||
val expectations = parseExpectations(dir, testFile)
|
||||
@@ -244,36 +275,35 @@ abstract class AbstractIrTextTestCase : AbstractIrGeneratorTestCase() {
|
||||
private val EXPECTED_OCCURRENCES_PATTERN = Regex("""^\s*//\s*(\d+)\s*(.*)$""")
|
||||
private val IR_FILE_TXT_PATTERN = Regex("""// IR_FILE: (.*)$""")
|
||||
|
||||
private val DUMP_DEPENDENCIES_PATTERN = Regex("""// !DUMP_DEPENDENCIES""")
|
||||
private val DUMP_EXTERNAL_CLASS = Regex("""// DUMP_EXTERNAL_CLASS (.*)""")
|
||||
|
||||
private val EXTERNAL_FILE_PATTERN = Regex("""// EXTERNAL_FILE""")
|
||||
|
||||
internal fun shouldDumpDependencies(wholeFile: File): Boolean =
|
||||
DUMP_DEPENDENCIES_PATTERN.containsMatchIn(wholeFile.readText())
|
||||
private inline fun <T> String.matchLinesWith(regex: Regex, ifMatched: (MatchResult) -> T): List<T> =
|
||||
split("\n").mapNotNull { regex.matchEntire(it)?.let(ifMatched) }
|
||||
|
||||
internal fun parseDumpExternalClasses(text: String) =
|
||||
text.matchLinesWith(DUMP_EXTERNAL_CLASS) { it.groupValues[1] }
|
||||
|
||||
internal fun TestFile.isExternalFile() =
|
||||
EXTERNAL_FILE_PATTERN.containsMatchIn(content)
|
||||
|
||||
internal fun KtFile.isExternalFile() =
|
||||
EXTERNAL_FILE_PATTERN.containsMatchIn(text)
|
||||
|
||||
internal fun parseExpectations(dir: File, testFile: TestFile): Expectations {
|
||||
val regexps = ArrayList<RegexpInText>()
|
||||
val treeFiles = ArrayList<IrTreeFileLabel>()
|
||||
|
||||
for (line in testFile.content.split("\n")) {
|
||||
EXPECTED_OCCURRENCES_PATTERN.matchEntire(line)?.let { matchResult ->
|
||||
regexps.add(RegexpInText(matchResult.groupValues[1], matchResult.groupValues[2].trim()))
|
||||
} ?: IR_FILE_TXT_PATTERN.find(line)?.let { matchResult ->
|
||||
val fileName = matchResult.groupValues[1].trim()
|
||||
val file = createExpectedTextFile(testFile, dir, fileName)
|
||||
treeFiles.add(IrTreeFileLabel(file, 0))
|
||||
val regexps =
|
||||
testFile.content.matchLinesWith(EXPECTED_OCCURRENCES_PATTERN) {
|
||||
RegexpInText(it.groupValues[1], it.groupValues[2].trim())
|
||||
}
|
||||
|
||||
var treeFiles =
|
||||
testFile.content.matchLinesWith(IR_FILE_TXT_PATTERN) {
|
||||
val fileName = it.groupValues[1].trim()
|
||||
val file = createExpectedTextFile(testFile, dir, fileName)
|
||||
IrTreeFileLabel(file, 0)
|
||||
}
|
||||
}
|
||||
|
||||
if (treeFiles.isEmpty()) {
|
||||
val file = createExpectedTextFile(testFile, dir, testFile.name.replace(".kt", ".txt"))
|
||||
treeFiles.add(IrTreeFileLabel(file, 0))
|
||||
treeFiles = listOf(IrTreeFileLabel(file, 0))
|
||||
}
|
||||
|
||||
return Expectations(regexps, treeFiles)
|
||||
|
||||
Reference in New Issue
Block a user