diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt index db06e6f2319..0991be19231 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt @@ -16,8 +16,8 @@ package org.jetbrains.kotlin.ir.util -import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* 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.utils.Printer -fun IrElement.dump(normalizeNames: Boolean = false): String = +fun IrElement.dump(normalizeNames: Boolean = false, stableOrder: Boolean = false): String = try { StringBuilder().also { sb -> - accept(DumpIrTreeVisitor(sb, normalizeNames), "") + accept(DumpIrTreeVisitor(sb, normalizeNames, stableOrder), "") }.toString() } catch (e: Exception) { "(Full dump is not available: ${e.message})\n" + render() @@ -44,13 +44,42 @@ fun IrFile.dumpTreesFromLineNumber(lineNumber: Int, normalizeNames: Boolean = fa class DumpIrTreeVisitor( out: Appendable, - normalizeNames: Boolean = false + normalizeNames: Boolean = false, + private val stableOrder: Boolean = false ) : IrElementVisitor { private val printer = Printer(out, " ") private val elementRenderer = RenderIrElementVisitor(normalizeNames) private fun IrType.render() = elementRenderer.renderType(this) + private fun List.ordered(): List { + if (!stableOrder) return this + + val strictOrder = mutableMapOf() + + 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) { element.dumpLabeledElementWith(data) { if (element is IrAnnotationContainer) { @@ -69,7 +98,7 @@ class DumpIrTreeVisitor( override fun visitFile(declaration: IrFile, data: String) { declaration.dumpLabeledElementWith(data) { dumpAnnotations(declaration) - declaration.declarations.dumpElements() + declaration.declarations.ordered().dumpElements() } } @@ -78,7 +107,7 @@ class DumpIrTreeVisitor( dumpAnnotations(declaration) declaration.thisReceiver?.accept(this, "\$this") declaration.typeParameters.dumpElements() - declaration.declarations.dumpElements() + declaration.declarations.ordered().dumpElements() } } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt index c9c385522e7..c0a7424eea4 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractKlibTextTestCase.kt @@ -83,7 +83,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { val ignoreErrors = AbstractIrGeneratorTestCase.shouldIgnoreErrors(wholeFile) val stdlib = loadKlibFromPath(listOf(runtimeKlibPath)).single() val (irModule, bindingContext) = buildFragmentAndLinkIt(stdlib, ignoreErrors, expectActualSymbols) - val expected = irModule.dump() + val expected = irModule.dump(stableOrder = true) val mppProject = myEnvironment.configuration.languageVersionSettings.getFeatureSupport(LanguageFeature.MultiPlatformProjects) == LanguageFeature.State.ENABLED val klibPath = serializeModule(irModule, bindingContext, stdlib, ignoreErrors, expectActualSymbols, !mppProject) @@ -91,7 +91,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() { val stdlib2 = libs[0] val klib = libs[1] val deserializedIrModule = deserializeModule(stdlib2, klib) - val actual = deserializedIrModule.dump() + val actual = deserializedIrModule.dump(stableOrder = true) try { TestCase.assertEquals(wholeFile.name, expected, actual)