Introduce new API for kotlinx-metadata-jvm

Kdocs are provided in a subsequent commit

 #KT-26602 Fixed
This commit is contained in:
Alexander Udalov
2019-05-03 19:40:43 +02:00
parent aa54a7e11a
commit 5ee34503c0
12 changed files with 1002 additions and 36 deletions
@@ -23,8 +23,9 @@ import java.io.File
import kotlin.test.fail
fun compileAndPrintAllFiles(file: File, disposable: Disposable, tmpdir: File, compareWithTxt: Boolean, readWriteAndCompare: Boolean) {
val read = StringBuilder()
val readWriteRead = StringBuilder()
val main = StringBuilder()
val afterVisitors = StringBuilder()
val afterNodes = StringBuilder()
val kotlinp = Kotlinp(KotlinpSettings(isVerbose = true))
@@ -32,18 +33,24 @@ fun compileAndPrintAllFiles(file: File, disposable: Disposable, tmpdir: File, co
when (outputFile.extension) {
"kotlin_module" -> {
val moduleFile = kotlinp.readModuleFile(outputFile)!!
val moduleFile2 = transformModuleFile(moduleFile)
val transformedWithVisitors = transformModuleFileWithReadWriteVisitors(moduleFile)
val transformedWithNodes = transformModuleFileWithNodes(moduleFile)
for ((sb, moduleFileToRender) in listOf(read to moduleFile, readWriteRead to moduleFile2)) {
for ((sb, moduleFileToRender) in listOf(
main to moduleFile, afterVisitors to transformedWithVisitors, afterNodes to transformedWithNodes
)) {
sb.appendFileName(outputFile.relativeTo(tmpdir))
sb.append(kotlinp.renderModuleFile(moduleFileToRender))
}
}
"class" -> {
val classFile = kotlinp.readClassFile(outputFile)!!
val classFile2 = transformClassFile(classFile)
val classFile2 = transformClassFileWithReadWriteVisitors(classFile)
val classFile3 = transformClassFileWithNodes(classFile)
for ((sb, classFileToRender) in listOf(read to classFile, readWriteRead to classFile2)) {
for ((sb, classFileToRender) in listOf(
main to classFile, afterVisitors to classFile2, afterNodes to classFile3
)) {
sb.appendFileName(outputFile.relativeTo(tmpdir))
sb.append(kotlinp.renderClassFile(classFileToRender))
}
@@ -53,11 +60,12 @@ fun compileAndPrintAllFiles(file: File, disposable: Disposable, tmpdir: File, co
}
if (compareWithTxt) {
KotlinTestUtils.assertEqualsToFile(File(file.path.replace(".kt", ".txt")), read.toString())
KotlinTestUtils.assertEqualsToFile(File(file.path.replace(".kt", ".txt")), main.toString())
}
if (readWriteAndCompare) {
assertEquals(read.toString(), readWriteRead.toString())
assertEquals("Metadata is different after transformation with visitors.", main.toString(), afterVisitors.toString())
assertEquals("Metadata is different after transformation with nodes.", main.toString(), afterNodes.toString())
}
}
@@ -85,7 +93,7 @@ private fun StringBuilder.appendFileName(file: File) {
// Reads the class file and writes it back with *Writer visitors.
// The resulting class file should be the same from the point of view of any metadata reader, including kotlinp
// (the exact bytes may differ though, because there are multiple ways to encode the same metadata)
private fun transformClassFile(classFile: KotlinClassMetadata): KotlinClassMetadata =
private fun transformClassFileWithReadWriteVisitors(classFile: KotlinClassMetadata): KotlinClassMetadata =
when (classFile) {
is KotlinClassMetadata.Class -> KotlinClassMetadata.Class.Writer().apply(classFile::accept).write()
is KotlinClassMetadata.FileFacade -> KotlinClassMetadata.FileFacade.Writer().apply(classFile::accept).write()
@@ -102,5 +110,22 @@ private fun transformClassFile(classFile: KotlinClassMetadata): KotlinClassMetad
else -> classFile
}
private fun transformModuleFile(moduleFile: KotlinModuleMetadata): KotlinModuleMetadata =
// Reads the class file and writes it back with KmClass/KmFunction/... elements.
private fun transformClassFileWithNodes(classFile: KotlinClassMetadata): KotlinClassMetadata =
when (classFile) {
is KotlinClassMetadata.Class ->
KotlinClassMetadata.Class.Writer().apply(classFile.toKmClass()::accept).write()
is KotlinClassMetadata.FileFacade ->
KotlinClassMetadata.FileFacade.Writer().apply(classFile.toKmPackage()::accept).write()
is KotlinClassMetadata.SyntheticClass ->
KotlinClassMetadata.SyntheticClass.Writer().apply { classFile.toKmLambda()?.accept(this) }.write()
is KotlinClassMetadata.MultiFileClassPart ->
KotlinClassMetadata.MultiFileClassPart.Writer().apply(classFile.toKmPackage()::accept).write(classFile.facadeClassName)
else -> classFile
}
private fun transformModuleFileWithReadWriteVisitors(moduleFile: KotlinModuleMetadata): KotlinModuleMetadata =
KotlinModuleMetadata.Writer().apply(moduleFile::accept).write()
private fun transformModuleFileWithNodes(moduleFile: KotlinModuleMetadata): KotlinModuleMetadata =
KotlinModuleMetadata.Writer().apply(moduleFile.toKmModule()::accept).write()