diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Kotlinp.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Kotlinp.kt index 36582b854d5..636d9db7670 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Kotlinp.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Kotlinp.kt @@ -10,17 +10,17 @@ import kotlinx.metadata.jvm.KotlinClassMetadata import kotlinx.metadata.jvm.KotlinModuleMetadata import java.io.File -object Kotlinp { +class Kotlinp(val settings: KotlinpSettings) { internal fun renderClassFile(classFile: KotlinClassMetadata?): String = when (classFile) { - is KotlinClassMetadata.Class -> ClassPrinter().print(classFile) - is KotlinClassMetadata.FileFacade -> FileFacadePrinter().print(classFile) + is KotlinClassMetadata.Class -> ClassPrinter(settings).print(classFile) + is KotlinClassMetadata.FileFacade -> FileFacadePrinter(settings).print(classFile) is KotlinClassMetadata.SyntheticClass -> { - if (classFile.isLambda) LambdaPrinter().print(classFile) + if (classFile.isLambda) LambdaPrinter(settings).print(classFile) else buildString { appendln("synthetic class") } } is KotlinClassMetadata.MultiFileClassFacade -> MultiFileClassFacadePrinter().print(classFile) - is KotlinClassMetadata.MultiFileClassPart -> MultiFileClassPartPrinter().print(classFile) + is KotlinClassMetadata.MultiFileClassPart -> MultiFileClassPartPrinter(settings).print(classFile) is KotlinClassMetadata.Unknown -> buildString { appendln("unknown file (k=${classFile.header.kind})") } null -> buildString { appendln("unsupported file") } } @@ -41,3 +41,7 @@ object Kotlinp { internal fun readModuleFile(file: File): KotlinModuleMetadata? = KotlinModuleMetadata.read(file.readBytes()) } + +data class KotlinpSettings( + val isVerbose: Boolean +) diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Main.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Main.kt index d6f667e255f..c243da4d0ed 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Main.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/Main.kt @@ -11,14 +11,17 @@ import java.io.IOException object Main { private fun run(args: Array) { val paths = arrayListOf() + var verbose = false var i = 0 while (true) { val arg = args.getOrNull(i++) ?: break - if ("-help" == arg || "-h" == arg) { + if (arg == "-help" || arg == "-h") { printUsageAndExit() - } else if ("-version" == arg) { + } else if (arg == "-verbose") { + verbose = true + } else if (arg == "-version") { printVersionAndExit() } else if (arg.startsWith("-")) { throw KotlinpException("unsupported argument: $arg") @@ -27,14 +30,16 @@ object Main { } } + val kotlinp = Kotlinp(KotlinpSettings(verbose)) + for (path in paths) { val file = File(path) if (!file.exists()) throw KotlinpException("file does not exist: $path") val text = try { when (file.extension) { - "class" -> Kotlinp.renderClassFile(Kotlinp.readClassFile(file)) - "kotlin_module" -> Kotlinp.renderModuleFile(Kotlinp.readModuleFile(file)) + "class" -> kotlinp.renderClassFile(kotlinp.readClassFile(file)) + "kotlin_module" -> kotlinp.renderModuleFile(kotlinp.readModuleFile(file)) else -> throw KotlinpException("only .class and .kotlin_module files are supported") } } catch (e: IOException) { @@ -65,6 +70,7 @@ object Main { Usage: kotlinp where possible options include: + -verbose Display information in more detail, minimizing ambiguities but worsening readability -version Display Kotlin version -help (-h) Print a synopsis of options """ diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt index a45b595c576..7cf0ac7b19f 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt @@ -12,7 +12,7 @@ private object SpecialCharacters { const val TYPE_ALIAS_MARKER = '^' } -private fun visitFunction(sb: StringBuilder, flags: Flags, name: String): KmFunctionVisitor = +private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: Flags, name: String): KmFunctionVisitor = object : KmFunctionVisitor() { val typeParams = mutableListOf() val params = mutableListOf() @@ -27,7 +27,7 @@ private fun visitFunction(sb: StringBuilder, flags: Flags, name: String): KmFunc override fun visitTypeParameter( flags: Flags, name: String, id: Int, variance: KmVariance ): KmTypeParameterVisitor? = - printTypeParameter(flags, name, id, variance) { typeParams.add(it) } + printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) } override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor? = printValueParameter(flags, name) { params.add(it) } @@ -74,7 +74,9 @@ private fun visitFunction(sb: StringBuilder, flags: Flags, name: String): KmFunc } } -private fun visitProperty(sb: StringBuilder, flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags): KmPropertyVisitor = +private fun visitProperty( + settings: KotlinpSettings, sb: StringBuilder, flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags +): KmPropertyVisitor = object : KmPropertyVisitor() { val typeParams = mutableListOf() var receiverParameterType: String? = null @@ -91,7 +93,7 @@ private fun visitProperty(sb: StringBuilder, flags: Flags, name: String, getterF printType(flags) { receiverParameterType = it } override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? = - printTypeParameter(flags, name, id, variance) { typeParams.add(it) } + printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) } override fun visitSetterParameter(flags: Flags, name: String): KmValueParameterVisitor? = printValueParameter(flags, name) { setterParameter = it } @@ -211,7 +213,7 @@ private fun visitConstructor(sb: StringBuilder, flags: Flags): KmConstructorVisi } } -private fun visitTypeAlias(sb: StringBuilder, flags: Flags, name: String): KmTypeAliasVisitor = +private fun visitTypeAlias(settings: KotlinpSettings, sb: StringBuilder, flags: Flags, name: String): KmTypeAliasVisitor = object : KmTypeAliasVisitor() { val annotations = mutableListOf() val typeParams = mutableListOf() @@ -220,7 +222,7 @@ private fun visitTypeAlias(sb: StringBuilder, flags: Flags, name: String): KmTyp var versionRequirement: String? = null override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? = - printTypeParameter(flags, name, id, variance) { typeParams.add(it) } + printTypeParameter(settings, flags, name, id, variance) { typeParams.add(it) } override fun visitUnderlyingType(flags: Flags): KmTypeVisitor? = printType(flags) { underlyingType = it } @@ -353,7 +355,7 @@ private fun printType(flags: Flags, output: (String) -> Unit): KmTypeVisitor = } private fun printTypeParameter( - flags: Flags, name: String, id: Int, variance: KmVariance, output: (String) -> Unit + settings: KotlinpSettings, flags: Flags, name: String, id: Int, variance: KmVariance, output: (String) -> Unit ): KmTypeParameterVisitor = object : KmTypeParameterVisitor() { val bounds = mutableListOf() @@ -380,7 +382,10 @@ private fun printTypeParameter( if (variance != KmVariance.INVARIANT) { append(variance.name.toLowerCase()).append(" ") } - append("T#$id /* $name */") + append("T#$id") + if (settings.isVerbose) { + append(" /* $name */") + } if (bounds.isNotEmpty()) { bounds.joinTo(this, separator = " & ", prefix = " : ") } @@ -506,7 +511,7 @@ interface AbstractPrinter { fun print(klass: T): String } -class ClassPrinter : KmClassVisitor(), AbstractPrinter { +class ClassPrinter(private val settings: KotlinpSettings) : KmClassVisitor(), AbstractPrinter { private val sb = StringBuilder() private val result = StringBuilder() @@ -540,7 +545,7 @@ class ClassPrinter : KmClassVisitor(), AbstractPrinter { +class FileFacadePrinter(settings: KotlinpSettings) : PackagePrinter(settings), AbstractPrinter { override fun print(klass: KotlinClassMetadata.FileFacade): String { klass.accept(this) return sb.toString() } } -class LambdaPrinter : KmLambdaVisitor(), AbstractPrinter { +class LambdaPrinter(private val settings: KotlinpSettings) : KmLambdaVisitor(), AbstractPrinter { private val sb = StringBuilder().apply { appendln("lambda {") } override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? = - visitFunction(sb, flags, name) + visitFunction(settings, sb, flags, name) override fun visitEnd() { sb.appendln("}") @@ -630,7 +635,9 @@ class LambdaPrinter : KmLambdaVisitor(), AbstractPrinter { +class MultiFileClassPartPrinter( + settings: KotlinpSettings +) : PackagePrinter(settings), AbstractPrinter { override fun print(klass: KotlinClassMetadata.MultiFileClassPart): String { sb.appendln(" // facade: ${klass.facadeClassName}") klass.accept(this) diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt index 876a3c61644..4d4b977a335 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.GenerationUtils import org.jetbrains.kotlin.kotlinp.Kotlinp +import org.jetbrains.kotlin.kotlinp.KotlinpSettings import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.TestJdkKind @@ -24,24 +25,26 @@ fun compileAndPrintAllFiles(file: File, disposable: Disposable, tmpdir: File, co val read = StringBuilder() val readWriteRead = StringBuilder() + val kotlinp = Kotlinp(KotlinpSettings(isVerbose = true)) + compile(file, disposable, tmpdir) { outputFile -> when (outputFile.extension) { "kotlin_module" -> { - val moduleFile = Kotlinp.readModuleFile(outputFile)!! + val moduleFile = kotlinp.readModuleFile(outputFile)!! val moduleFile2 = transformModuleFile(moduleFile) for ((sb, moduleFileToRender) in listOf(read to moduleFile, readWriteRead to moduleFile2)) { sb.appendFileName(outputFile.relativeTo(tmpdir)) - sb.append(Kotlinp.renderModuleFile(moduleFileToRender)) + sb.append(kotlinp.renderModuleFile(moduleFileToRender)) } } "class" -> { - val classFile = Kotlinp.readClassFile(outputFile)!! + val classFile = kotlinp.readClassFile(outputFile)!! val classFile2 = transformClassFile(classFile) for ((sb, classFileToRender) in listOf(read to classFile, readWriteRead to classFile2)) { sb.appendFileName(outputFile.relativeTo(tmpdir)) - sb.append(Kotlinp.renderClassFile(classFileToRender)) + sb.append(kotlinp.renderClassFile(classFileToRender)) } } else -> fail("Unknown file: $outputFile")