[IR] Support stable order in IR dump
That mode is need to test deserialization of klibs
This commit is contained in:
committed by
teamcityserver
parent
bbcd511c44
commit
2eac442705
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.util
|
package org.jetbrains.kotlin.ir.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrFileEntry
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.IrFileEntry
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -27,10 +27,10 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
fun IrElement.dump(normalizeNames: Boolean = false): String =
|
fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String =
|
||||||
try {
|
try {
|
||||||
StringBuilder().also { sb ->
|
StringBuilder().also { sb ->
|
||||||
accept(DumpIrTreeVisitor(sb, normalizeNames), "")
|
accept(DumpIrTreeVisitor(sb, normalizeNames, stableOrder), "")
|
||||||
}.toString()
|
}.toString()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
"(Full dump is not available: ${e.message})\n" + render()
|
"(Full dump is not available: ${e.message})\n" + render()
|
||||||
@@ -44,13 +44,42 @@ fun IrFile.dumpTreesFromLineNumber(lineNumber: Int, normalizeNames: Boolean = fa
|
|||||||
|
|
||||||
class DumpIrTreeVisitor(
|
class DumpIrTreeVisitor(
|
||||||
out: Appendable,
|
out: Appendable,
|
||||||
normalizeNames: Boolean = false
|
normalizeNames: Boolean = false,
|
||||||
|
private val stableOrder: Boolean = false
|
||||||
) : IrElementVisitor<Unit, String> {
|
) : IrElementVisitor<Unit, String> {
|
||||||
|
|
||||||
private val printer = Printer(out, " ")
|
private val printer = Printer(out, " ")
|
||||||
private val elementRenderer = RenderIrElementVisitor(normalizeNames)
|
private val elementRenderer = RenderIrElementVisitor(normalizeNames)
|
||||||
private fun IrType.render() = elementRenderer.renderType(this)
|
private fun IrType.render() = elementRenderer.renderType(this)
|
||||||
|
|
||||||
|
private fun List<IrDeclaration>.ordered(): List<IrDeclaration> {
|
||||||
|
if (!stableOrder) return this
|
||||||
|
|
||||||
|
val strictOrder = mutableMapOf<IrDeclaration, Int>()
|
||||||
|
|
||||||
|
var idx = 0
|
||||||
|
|
||||||
|
forEach {
|
||||||
|
if (it is IrProperty && it.backingField != null && !it.isConst) {
|
||||||
|
strictOrder[it] = idx++
|
||||||
|
}
|
||||||
|
if (it is IrAnonymousInitializer) {
|
||||||
|
strictOrder[it] = idx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedWith { a, b ->
|
||||||
|
val strictA = strictOrder[a] ?: Int.MAX_VALUE
|
||||||
|
val strictB = strictOrder[b] ?: Int.MAX_VALUE
|
||||||
|
|
||||||
|
if (strictA == strictB) {
|
||||||
|
val rA = a.render()
|
||||||
|
val rB = b.render()
|
||||||
|
rA.compareTo(rB)
|
||||||
|
} else strictA - strictB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitElement(element: IrElement, data: String) {
|
override fun visitElement(element: IrElement, data: String) {
|
||||||
element.dumpLabeledElementWith(data) {
|
element.dumpLabeledElementWith(data) {
|
||||||
if (element is IrAnnotationContainer) {
|
if (element is IrAnnotationContainer) {
|
||||||
@@ -69,7 +98,7 @@ class DumpIrTreeVisitor(
|
|||||||
override fun visitFile(declaration: IrFile, data: String) {
|
override fun visitFile(declaration: IrFile, data: String) {
|
||||||
declaration.dumpLabeledElementWith(data) {
|
declaration.dumpLabeledElementWith(data) {
|
||||||
dumpAnnotations(declaration)
|
dumpAnnotations(declaration)
|
||||||
declaration.declarations.dumpElements()
|
declaration.declarations.ordered().dumpElements()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +107,7 @@ class DumpIrTreeVisitor(
|
|||||||
dumpAnnotations(declaration)
|
dumpAnnotations(declaration)
|
||||||
declaration.thisReceiver?.accept(this, "\$this")
|
declaration.thisReceiver?.accept(this, "\$this")
|
||||||
declaration.typeParameters.dumpElements()
|
declaration.typeParameters.dumpElements()
|
||||||
declaration.declarations.dumpElements()
|
declaration.declarations.ordered().dumpElements()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
|
|||||||
val ignoreErrors = AbstractIrGeneratorTestCase.shouldIgnoreErrors(wholeFile)
|
val ignoreErrors = AbstractIrGeneratorTestCase.shouldIgnoreErrors(wholeFile)
|
||||||
val stdlib = loadKlibFromPath(listOf(runtimeKlibPath)).single()
|
val stdlib = loadKlibFromPath(listOf(runtimeKlibPath)).single()
|
||||||
val (irModule, bindingContext) = buildFragmentAndLinkIt(stdlib, ignoreErrors, expectActualSymbols)
|
val (irModule, bindingContext) = buildFragmentAndLinkIt(stdlib, ignoreErrors, expectActualSymbols)
|
||||||
val expected = irModule.dump()
|
val expected = irModule.dump(stableOrder = true)
|
||||||
val mppProject =
|
val mppProject =
|
||||||
myEnvironment.configuration.languageVersionSettings.getFeatureSupport(LanguageFeature.MultiPlatformProjects) == LanguageFeature.State.ENABLED
|
myEnvironment.configuration.languageVersionSettings.getFeatureSupport(LanguageFeature.MultiPlatformProjects) == LanguageFeature.State.ENABLED
|
||||||
val klibPath = serializeModule(irModule, bindingContext, stdlib, ignoreErrors, expectActualSymbols, !mppProject)
|
val klibPath = serializeModule(irModule, bindingContext, stdlib, ignoreErrors, expectActualSymbols, !mppProject)
|
||||||
@@ -91,7 +91,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
|
|||||||
val stdlib2 = libs[0]
|
val stdlib2 = libs[0]
|
||||||
val klib = libs[1]
|
val klib = libs[1]
|
||||||
val deserializedIrModule = deserializeModule(stdlib2, klib)
|
val deserializedIrModule = deserializeModule(stdlib2, klib)
|
||||||
val actual = deserializedIrModule.dump()
|
val actual = deserializedIrModule.dump(stableOrder = true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TestCase.assertEquals(wholeFile.name, expected, actual)
|
TestCase.assertEquals(wholeFile.name, expected, actual)
|
||||||
|
|||||||
Reference in New Issue
Block a user