Add kotlinp, a tool to print Kotlin metadata in class/module files

At the moment, it's not published anywhere, but that may change soon

 #KT-23198
This commit is contained in:
Alexander Udalov
2018-03-09 14:40:47 +01:00
parent e4062f6447
commit 4b284a4890
34 changed files with 1687 additions and 0 deletions
@@ -46,6 +46,7 @@ class CodeConformanceTest : TestCase() {
"dist",
"libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build/tmp",
"libraries/tools/kotlin-maven-plugin/target",
"libraries/tools/kotlinp/src",
"compiler/testData/psi/kdoc",
"compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt",
"compiler/util/src/org/jetbrains/kotlin/config/MavenComparableVersion.java"
+40
View File
@@ -0,0 +1,40 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
description = "kotlinp"
plugins {
kotlin("jvm")
}
val shadows by configurations.creating
shadows.extendsFrom(configurations.getByName("compile"))
dependencies {
compile(project(":kotlinx-metadata"))
compile(project(":kotlinx-metadata-jvm"))
// We use an older version of ASM on purpose, to reduce the final application size
compile("org.ow2.asm:asm:4.0")
testCompile(commonDep("junit:junit"))
testCompile(projectTests(":generators:test-generator"))
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
projectTest {
workingDir = rootDir
}
val generateTests by generator("org.jetbrains.kotlin.kotlinp.test.GenerateKotlinpTestsKt")
val shadowJar by task<ShadowJar> {
classifier = "shadow"
version = null
configurations = listOf(shadows)
from(the<JavaPluginConvention>().sourceSets.getByName("main").output)
manifest {
attributes["Main-Class"] = "org.jetbrains.kotlin.kotlinp.Main"
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp
import kotlinx.metadata.InconsistentKotlinMetadataException
import kotlinx.metadata.jvm.KotlinClassMetadata
import java.io.File
object Kotlinp {
internal fun renderClassFile(classFile: KotlinClassMetadata?): String =
when (classFile) {
is KotlinClassMetadata.Class -> ClassPrinter().print(classFile)
is KotlinClassMetadata.FileFacade -> FileFacadePrinter().print(classFile)
is KotlinClassMetadata.SyntheticClass -> {
if (classFile.isLambda) LambdaPrinter().print(classFile)
else buildString { appendln("synthetic class") }
}
is KotlinClassMetadata.MultiFileClassFacade -> MultiFileClassFacadePrinter().print(classFile)
is KotlinClassMetadata.MultiFileClassPart -> MultiFileClassPartPrinter().print(classFile)
is KotlinClassMetadata.Unknown -> buildString { appendln("unknown file (k=${classFile.header.kind})") }
null -> buildString { appendln("unsupported file") }
}
internal fun readClassFile(file: File): KotlinClassMetadata? {
val header = file.readKotlinClassHeader() ?: throw KotlinpException("file is not a Kotlin class file: $file")
return try {
KotlinClassMetadata.read(header)
} catch (e: InconsistentKotlinMetadataException) {
throw KotlinpException("inconsistent Kotlin metadata: ${e.message}")
}
}
}
@@ -0,0 +1,8 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp
class KotlinpException(message: String) : RuntimeException(message)
@@ -0,0 +1,78 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp
import java.io.File
import java.io.IOException
object Main {
private fun run(args: Array<String>) {
val paths = arrayListOf<String>()
var i = 0
while (true) {
val arg = args.getOrNull(i++) ?: break
if ("-help" == arg || "-h" == arg) {
printUsageAndExit()
} else if ("-version" == arg) {
printVersionAndExit()
} else if (arg.startsWith("-")) {
throw KotlinpException("unsupported argument: $arg")
} else {
paths.add(arg)
}
}
for (path in paths) {
if (!path.endsWith(".class")) throw KotlinpException("only .class files are supported")
val file = File(path)
if (!file.exists()) throw KotlinpException("file does not exist: $path")
try {
print(Kotlinp.renderClassFile(Kotlinp.readClassFile(file)))
} catch (e: IOException) {
throw KotlinpException("I/O operation failed: ${e.message}")
}
}
if (paths.isEmpty()) {
throw KotlinpException("no files specified")
}
}
@JvmStatic
fun main(args: Array<String>) {
try {
run(args)
} catch (e: KotlinpException) {
System.err.println("error: " + e.message)
System.exit(1)
}
}
private fun printUsageAndExit() {
println(
"""kotlinp: print Kotlin declarations in the given class file.
Usage: kotlinp <options> <classes>
where possible options include:
-version Display Kotlin version
-help (-h) Print a synopsis of options
"""
)
System.exit(0)
}
private fun printVersionAndExit() {
// TODO: get version from manifest
val version = "@snapshot@"
println("Kotlin version " + version + " (JRE " + System.getProperty("java.runtime.version") + ")")
System.exit(0)
}
}
@@ -0,0 +1,731 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp
import kotlinx.metadata.*
import kotlinx.metadata.jvm.*
private object SpecialCharacters {
const val TYPE_ALIAS_MARKER = '^'
}
private fun visitFunction(sb: StringBuilder, flags: Int, name: String): KmFunctionVisitor =
object : KmFunctionVisitor() {
val typeParams = mutableListOf<String>()
val params = mutableListOf<String>()
var receiverParameterType: String? = null
var returnType: String? = null
var versionRequirement: String? = null
var jvmDesc: String? = null
override fun visitReceiverParameterType(flags: Int): KmTypeVisitor? =
printType(flags) { receiverParameterType = it }
override fun visitTypeParameter(
flags: Int, name: String, id: Int, variance: KmVariance
): KmTypeParameterVisitor? =
printTypeParameter(flags, name, id, variance) { typeParams.add(it) }
override fun visitValueParameter(flags: Int, name: String): KmValueParameterVisitor? =
printValueParameter(flags, name) { params.add(it) }
override fun visitReturnType(flags: Int): KmTypeVisitor? =
printType(flags) { returnType = it }
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it }
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? {
if (type != JvmFunctionExtensionVisitor.TYPE) return null
return object : JvmFunctionExtensionVisitor() {
override fun visit(desc: String?) {
jvmDesc = desc
}
}
}
override fun visitEnd() {
sb.appendln()
if (versionRequirement != null) {
sb.appendln(" // $versionRequirement")
}
if (jvmDesc != null) {
sb.appendln(" // signature: $jvmDesc")
}
sb.append(" ")
sb.appendFlags(flags, FUNCTION_FLAGS_MAP)
sb.append("fun ")
if (typeParams.isNotEmpty()) {
typeParams.joinTo(sb, prefix = "<", postfix = ">")
sb.append(" ")
}
if (receiverParameterType != null) {
sb.append(receiverParameterType).append(".")
}
sb.append(name)
params.joinTo(sb, prefix = "(", postfix = ")")
if (returnType != null) {
sb.append(": ").append(returnType)
}
sb.appendln()
}
}
private fun visitProperty(sb: StringBuilder, flags: Int, name: String, getterFlags: Int, setterFlags: Int): KmPropertyVisitor =
object : KmPropertyVisitor() {
val typeParams = mutableListOf<String>()
var receiverParameterType: String? = null
var returnType: String? = null
var setterParameter: String? = null
var versionRequirement: String? = null
var jvmFieldName: String? = null
var jvmFieldTypeDesc: String? = null
var jvmGetterDesc: String? = null
var jvmSetterDesc: String? = null
var jvmSyntheticMethodForAnnotationsDesc: String? = null
override fun visitReceiverParameterType(flags: Int): KmTypeVisitor? =
printType(flags) { receiverParameterType = it }
override fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
printTypeParameter(flags, name, id, variance) { typeParams.add(it) }
override fun visitSetterParameter(flags: Int, name: String): KmValueParameterVisitor? =
printValueParameter(flags, name) { setterParameter = it }
override fun visitReturnType(flags: Int): KmTypeVisitor? =
printType(flags) { returnType = it }
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it }
override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor? {
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
override fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
jvmFieldName = fieldName
jvmFieldTypeDesc = fieldTypeDesc
jvmGetterDesc = getterDesc
jvmSetterDesc = setterDesc
}
override fun visitSyntheticMethodForAnnotations(desc: String?) {
jvmSyntheticMethodForAnnotationsDesc = desc
}
}
}
override fun visitEnd() {
sb.appendln()
if (versionRequirement != null) {
sb.appendln(" // $versionRequirement")
}
if (jvmFieldName != null || jvmFieldTypeDesc != null) {
sb.append(" // field: ${jvmFieldName ?: "<null>"}")
if (jvmFieldTypeDesc != null) {
sb.append(":$jvmFieldTypeDesc")
}
sb.appendln()
}
if (jvmGetterDesc != null) {
sb.appendln(" // getter: $jvmGetterDesc")
}
if (jvmSetterDesc != null) {
sb.appendln(" // setter: $jvmSetterDesc")
}
if (jvmSyntheticMethodForAnnotationsDesc != null) {
sb.appendln(" // synthetic method for annotations: $jvmSyntheticMethodForAnnotationsDesc")
}
sb.append(" ")
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
sb.append(if (Flags.Property.IS_VAR(flags)) "var " else "val ")
if (typeParams.isNotEmpty()) {
typeParams.joinTo(sb, prefix = "<", postfix = ">")
sb.append(" ")
}
if (receiverParameterType != null) {
sb.append(receiverParameterType).append(".")
}
sb.append(name)
if (returnType != null) {
sb.append(": ").append(returnType)
}
if (Flags.Property.HAS_CONSTANT(flags)) {
sb.append(" /* = ... */")
}
sb.appendln()
if (Flags.Property.HAS_GETTER(flags)) {
sb.append(" ")
sb.appendFlags(getterFlags, PROPERTY_ACCESSOR_FLAGS_MAP)
sb.appendln("get")
}
if (Flags.Property.HAS_SETTER(flags)) {
sb.append(" ")
sb.appendFlags(setterFlags, PROPERTY_ACCESSOR_FLAGS_MAP)
sb.append("set")
if (setterParameter != null) {
sb.append("(").append(setterParameter).append(")")
}
sb.appendln()
}
}
}
private fun visitConstructor(sb: StringBuilder, flags: Int): KmConstructorVisitor =
object : KmConstructorVisitor() {
val params = mutableListOf<String>()
var versionRequirement: String? = null
var jvmDesc: String? = null
override fun visitValueParameter(flags: Int, name: String): KmValueParameterVisitor? =
printValueParameter(flags, name) { params.add(it) }
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it }
override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor? {
if (type != JvmConstructorExtensionVisitor.TYPE) return null
return object : JvmConstructorExtensionVisitor() {
override fun visit(desc: String?) {
jvmDesc = desc
}
}
}
override fun visitEnd() {
sb.appendln()
if (versionRequirement != null) {
sb.appendln(" // $versionRequirement")
}
if (jvmDesc != null) {
sb.appendln(" // signature: $jvmDesc")
}
sb.append(" ")
sb.appendFlags(flags, CONSTRUCTOR_FLAGS_MAP)
sb.append("constructor(")
params.joinTo(sb)
sb.appendln(")")
}
}
private fun visitTypeAlias(sb: StringBuilder, flags: Int, name: String): KmTypeAliasVisitor =
object : KmTypeAliasVisitor() {
val annotations = mutableListOf<KmAnnotation>()
val typeParams = mutableListOf<String>()
var underlyingType: String? = null
var expandedType: String? = null
var versionRequirement: String? = null
override fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
printTypeParameter(flags, name, id, variance) { typeParams.add(it) }
override fun visitUnderlyingType(flags: Int): KmTypeVisitor? =
printType(flags) { underlyingType = it }
override fun visitExpandedType(flags: Int): KmTypeVisitor? =
printType(flags) { expandedType = it }
override fun visitAnnotation(annotation: KmAnnotation) {
annotations += annotation
}
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it }
override fun visitEnd() {
sb.appendln()
if (versionRequirement != null) {
sb.appendln(" // $versionRequirement")
}
for (annotation in annotations) {
sb.append(" ").append("@").append(renderAnnotation(annotation)).appendln()
}
sb.append(" ")
sb.appendFlags(flags, VISIBILITY_FLAGS_MAP)
sb.append("typealias ").append(name)
if (typeParams.isNotEmpty()) {
typeParams.joinTo(sb, prefix = "<", postfix = ">")
}
if (underlyingType != null) {
sb.append(" = ").append(underlyingType)
}
if (expandedType != null) {
sb.append(" /* = ").append(expandedType).append(" */")
}
sb.appendln()
}
}
private fun printType(flags: Int, output: (String) -> Unit): KmTypeVisitor =
object : KmTypeVisitor() {
var classifier: String? = null
val arguments = mutableListOf<String>()
var abbreviatedType: String? = null
var outerType: String? = null
var platformTypeUpperBound: String? = null
var jvmIsRaw: Boolean? = null
var jvmAnnotations = mutableListOf<KmAnnotation>()
override fun visitClass(name: ClassName) {
classifier = name
}
override fun visitTypeParameter(id: Int) {
classifier = "T#$id"
}
override fun visitTypeAlias(name: ClassName) {
classifier = "$name${SpecialCharacters.TYPE_ALIAS_MARKER}"
}
override fun visitAbbreviatedType(flags: Int): KmTypeVisitor? =
printType(flags) { abbreviatedType = it }
override fun visitArgument(flags: Int, variance: KmVariance): KmTypeVisitor? =
printType(flags) { argumentTypeString ->
arguments += buildString {
if (variance != KmVariance.INVARIANT) {
append(variance.name.toLowerCase()).append(" ")
}
append(argumentTypeString)
}
}
override fun visitStarProjection() {
arguments += "*"
}
override fun visitOuterType(flags: Int): KmTypeVisitor? =
printType(flags) { outerType = it }
override fun visitFlexibleTypeUpperBound(flags: Int, typeFlexibilityId: String?): KmTypeVisitor? =
if (typeFlexibilityId == JvmTypeExtensionVisitor.PLATFORM_TYPE_ID) {
printType(flags) { platformTypeUpperBound = it }
} else null
override fun visitExtensions(type: KmExtensionType): KmTypeExtensionVisitor? {
if (type != JvmTypeExtensionVisitor.TYPE) return null
return object : JvmTypeExtensionVisitor() {
override fun visit(isRaw: Boolean) {
jvmIsRaw = isRaw
}
override fun visitAnnotation(annotation: KmAnnotation) {
jvmAnnotations.add(annotation)
}
}
}
override fun visitEnd() {
output(buildString {
for (annotation in jvmAnnotations) {
append("@").append(renderAnnotation(annotation)).append(" ")
}
if (jvmIsRaw == true) {
append("/* raw */ ")
}
appendFlags(flags, TYPE_FLAGS_MAP)
if (outerType != null) {
append(outerType).append(".").append(classifier?.substringAfterLast('.'))
} else {
append(classifier)
}
if (arguments.isNotEmpty()) {
arguments.joinTo(this, prefix = "<", postfix = ">")
}
if (Flags.Type.IS_NULLABLE(flags)) {
append("?")
}
if (abbreviatedType != null) {
append(" /* = ").append(abbreviatedType).append(" */")
}
if (platformTypeUpperBound == "$this?") {
append("!")
} else if (platformTypeUpperBound != null) {
append("..").append(platformTypeUpperBound)
}
})
}
}
private fun printTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance, output: (String) -> Unit): KmTypeParameterVisitor =
object : KmTypeParameterVisitor() {
val bounds = mutableListOf<String>()
val jvmAnnotations = mutableListOf<KmAnnotation>()
override fun visitUpperBound(flags: Int): KmTypeVisitor? =
printType(flags) { bounds += it }
override fun visitExtensions(type: KmExtensionType): KmTypeParameterExtensionVisitor? {
if (type != JvmTypeParameterExtensionVisitor.TYPE) return null
return object : JvmTypeParameterExtensionVisitor() {
override fun visitAnnotation(annotation: KmAnnotation) {
jvmAnnotations.add(annotation)
}
}
}
override fun visitEnd() {
output(buildString {
appendFlags(flags, TYPE_PARAMETER_FLAGS_MAP)
for (annotation in jvmAnnotations) {
append("@").append(renderAnnotation(annotation)).append(" ")
}
if (variance != KmVariance.INVARIANT) {
append(variance.name.toLowerCase()).append(" ")
}
append("T#$id /* $name */")
if (bounds.isNotEmpty()) {
bounds.joinTo(this, separator = " & ", prefix = " : ")
}
})
}
}
private fun printValueParameter(flags: Int, name: String, output: (String) -> Unit): KmValueParameterVisitor =
object : KmValueParameterVisitor() {
var varargElementType: String? = null
var type: String? = null
override fun visitType(flags: Int): KmTypeVisitor? =
printType(flags) { type = it }
override fun visitVarargElementType(flags: Int): KmTypeVisitor? =
printType(flags) { varargElementType = it }
override fun visitEnd() {
output(buildString {
appendFlags(flags, VALUE_PARAMETER_FLAGS_MAP)
if (varargElementType != null) {
append("vararg ").append(name).append(": ").append(varargElementType).append(" /* ").append(type).append(" */")
} else {
append(name).append(": ").append(type)
}
if (Flags.ValueParameter.DECLARES_DEFAULT_VALUE(flags)) {
append(" /* = ... */")
}
})
}
}
private fun renderAnnotation(annotation: KmAnnotation): String =
annotation.className + if (annotation.arguments.isEmpty()) "" else
annotation.arguments.entries.joinToString(prefix = "(", postfix = ")") { (name, argument) ->
"$name = ${renderAnnotationArgument(argument)}"
}
private fun renderAnnotationArgument(arg: KmAnnotationArgument<*>): String =
when (arg) {
is KmAnnotationArgument.ByteValue -> arg.value.toString() + ".toByte()"
is KmAnnotationArgument.CharValue -> "'${arg.value.toString().sanitize(quote = '\'')}'"
is KmAnnotationArgument.ShortValue -> arg.value.toString() + ".toShort()"
is KmAnnotationArgument.IntValue -> arg.value.toString()
is KmAnnotationArgument.LongValue -> arg.value.toString() + "L"
is KmAnnotationArgument.FloatValue -> arg.value.toString() + "f"
is KmAnnotationArgument.DoubleValue -> arg.value.toString()
is KmAnnotationArgument.BooleanValue -> arg.value.toString()
is KmAnnotationArgument.StringValue -> "\"${arg.value.sanitize(quote = '"')}\""
is KmAnnotationArgument.KClassValue -> "${arg.value}::class"
is KmAnnotationArgument.EnumValue -> arg.value
is KmAnnotationArgument.AnnotationValue -> arg.value.let { annotation ->
val args = annotation.arguments.entries.joinToString { (name, argument) ->
"$name = ${renderAnnotationArgument(argument)}"
}
"${annotation.className}($args)"
}
is KmAnnotationArgument.ArrayValue -> arg.value.joinToString(prefix = "[", postfix = "]", transform = ::renderAnnotationArgument)
}
private fun String.sanitize(quote: Char): String =
buildString(length) {
for (c in this@sanitize) {
when (c) {
'\n' -> append("\\n")
'\r' -> append("\\r")
'\t' -> append("\\t")
quote -> append("\\").append(quote)
else -> append(if (c.isISOControl()) "\\u%04x".format(c.toInt()) else c)
}
}
}
private fun printVersionRequirement(output: (String) -> Unit): KmVersionRequirementVisitor =
object : KmVersionRequirementVisitor() {
var kind: KmVersionRequirementVersionKind? = null
var level: KmVersionRequirementLevel? = null
var errorCode: Int? = null
var message: String? = null
var version: String? = null
override fun visit(kind: KmVersionRequirementVersionKind, level: KmVersionRequirementLevel, errorCode: Int?, message: String?) {
this.kind = kind
this.level = level
this.errorCode = errorCode
this.message = message
}
override fun visitVersion(major: Int, minor: Int, patch: Int) {
version = "$major.$minor.$patch"
}
override fun visitEnd() {
output(buildString {
append("requires ").append(
when (kind!!) {
KmVersionRequirementVersionKind.LANGUAGE_VERSION -> "language version"
KmVersionRequirementVersionKind.COMPILER_VERSION -> "compiler version"
KmVersionRequirementVersionKind.API_VERSION -> "API version"
}
).append(" ").append(version)
listOfNotNull(
"level=$level",
errorCode?.let { "errorCode=$it" },
message?.let { "message=\"$it\"" }
).joinTo(this, prefix = " (", postfix = ")")
})
}
}
private fun StringBuilder.appendFlags(flags: Int, map: Map<MetadataFlag, String>) {
for ((modifier, string) in map) {
if (modifier(flags)) {
append(string)
if (string.isNotEmpty()) append(" ")
}
}
}
interface AbstractPrinter<in T : KotlinClassMetadata> {
fun print(klass: T): String
}
class ClassPrinter : KmClassVisitor(), AbstractPrinter<KotlinClassMetadata.Class> {
private val sb = StringBuilder()
private val result = StringBuilder()
private var flags: Int? = null
private var name: ClassName? = null
private val typeParams = mutableListOf<String>()
private val supertypes = mutableListOf<String>()
private var versionRequirement: String? = null
override fun visit(flags: Int, name: ClassName) {
this.flags = flags
this.name = name
}
override fun visitEnd() {
if (versionRequirement != null) {
result.appendln(" // $versionRequirement")
}
result.appendFlags(flags!!, CLASS_FLAGS_MAP)
result.append(name)
if (typeParams.isNotEmpty()) {
typeParams.joinTo(result, prefix = "<", postfix = ">")
}
if (supertypes.isNotEmpty()) {
result.append(" : ")
supertypes.joinTo(result)
}
result.appendln(" {")
result.append(sb)
result.appendln("}")
}
override fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
printTypeParameter(flags, name, id, variance) { typeParams.add(it) }
override fun visitSupertype(flags: Int): KmTypeVisitor? =
printType(flags) { supertypes.add(it) }
override fun visitConstructor(flags: Int): KmConstructorVisitor? =
visitConstructor(sb, flags)
override fun visitFunction(flags: Int, name: String): KmFunctionVisitor? =
visitFunction(sb, flags, name)
override fun visitProperty(flags: Int, name: String, getterFlags: Int, setterFlags: Int): KmPropertyVisitor? =
visitProperty(sb, flags, name, getterFlags, setterFlags)
override fun visitTypeAlias(flags: Int, name: String): KmTypeAliasVisitor? =
visitTypeAlias(sb, flags, name)
override fun visitCompanionObject(name: String) {
sb.appendln()
sb.appendln(" // companion object: $name")
}
override fun visitNestedClass(name: String) {
sb.appendln()
sb.appendln(" // nested class: $name")
}
override fun visitEnumEntry(name: String) {
sb.appendln()
sb.appendln(" $name,")
}
override fun visitSealedSubclass(name: ClassName) {
sb.appendln()
sb.appendln(" // sealed subclass: $name")
}
override fun visitVersionRequirement(): KmVersionRequirementVisitor? =
printVersionRequirement { versionRequirement = it }
override fun print(klass: KotlinClassMetadata.Class): String {
klass.accept(this)
return result.toString()
}
}
abstract class PackagePrinter : KmPackageVisitor() {
internal val sb = StringBuilder().apply {
appendln("package {")
}
override fun visitEnd() {
sb.appendln("}")
}
override fun visitFunction(flags: Int, name: String): KmFunctionVisitor? =
visitFunction(sb, flags, name)
override fun visitProperty(flags: Int, name: String, getterFlags: Int, setterFlags: Int): KmPropertyVisitor? =
visitProperty(sb, flags, name, getterFlags, setterFlags)
override fun visitTypeAlias(flags: Int, name: String): KmTypeAliasVisitor? =
visitTypeAlias(sb, flags, name)
}
class FileFacadePrinter : PackagePrinter(), AbstractPrinter<KotlinClassMetadata.FileFacade> {
override fun print(klass: KotlinClassMetadata.FileFacade): String {
klass.accept(this)
return sb.toString()
}
}
class LambdaPrinter : KmLambdaVisitor(), AbstractPrinter<KotlinClassMetadata.SyntheticClass> {
private val sb = StringBuilder().apply {
appendln("lambda {")
}
override fun visitFunction(flags: Int, name: String): KmFunctionVisitor? =
visitFunction(sb, flags, name)
override fun visitEnd() {
sb.appendln("}")
}
override fun print(klass: KotlinClassMetadata.SyntheticClass): String {
klass.accept(this)
return sb.toString()
}
}
class MultiFileClassPartPrinter : PackagePrinter(), AbstractPrinter<KotlinClassMetadata.MultiFileClassPart> {
override fun print(klass: KotlinClassMetadata.MultiFileClassPart): String {
sb.appendln(" // facade: ${klass.facadeClassName}")
klass.accept(this)
return sb.toString()
}
}
class MultiFileClassFacadePrinter : AbstractPrinter<KotlinClassMetadata.MultiFileClassFacade> {
override fun print(klass: KotlinClassMetadata.MultiFileClassFacade): String =
buildString {
appendln("multi-file class {")
for (part in klass.partClassNames) {
appendln(" // $part")
}
appendln("}")
}
}
private val VISIBILITY_FLAGS_MAP = mapOf(
Flags.IS_INTERNAL to "internal",
Flags.IS_PRIVATE to "private",
Flags.IS_PRIVATE_TO_THIS to "private",
Flags.IS_PROTECTED to "protected",
Flags.IS_PUBLIC to "public",
Flags.IS_LOCAL to "local"
)
private val COMMON_FLAGS_MAP = VISIBILITY_FLAGS_MAP + mapOf(
Flags.IS_FINAL to "final",
Flags.IS_OPEN to "open",
Flags.IS_ABSTRACT to "abstract",
Flags.IS_SEALED to "sealed"
)
private val CLASS_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flags.Class.IS_INNER to "inner",
Flags.Class.IS_DATA to "data",
Flags.Class.IS_EXTERNAL to "external",
Flags.Class.IS_EXPECT to "expect",
Flags.Class.IS_INLINE to "inline",
Flags.Class.IS_CLASS to "class",
Flags.Class.IS_INTERFACE to "interface",
Flags.Class.IS_ENUM_CLASS to "enum class",
Flags.Class.IS_ENUM_ENTRY to "enum entry",
Flags.Class.IS_ANNOTATION_CLASS to "annotation class",
Flags.Class.IS_OBJECT to "object",
Flags.Class.IS_COMPANION_OBJECT to "companion object"
)
private val CONSTRUCTOR_FLAGS_MAP = VISIBILITY_FLAGS_MAP + mapOf(
Flags.Constructor.IS_PRIMARY to "/* primary */"
)
private val FUNCTION_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flags.Function.IS_DECLARATION to "",
Flags.Function.IS_FAKE_OVERRIDE to "/* fake override */",
Flags.Function.IS_DELEGATION to "/* delegation */",
Flags.Function.IS_SYNTHESIZED to "/* synthesized */",
Flags.Function.IS_OPERATOR to "operator",
Flags.Function.IS_INFIX to "infix",
Flags.Function.IS_INLINE to "inline",
Flags.Function.IS_TAILREC to "tailrec",
Flags.Function.IS_EXTERNAL to "external",
Flags.Function.IS_SUSPEND to "suspend",
Flags.Function.IS_EXPECT to "expect"
)
private val PROPERTY_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flags.Property.IS_DECLARATION to "",
Flags.Property.IS_FAKE_OVERRIDE to "/* fake override */",
Flags.Property.IS_DELEGATION to "/* delegation */",
Flags.Property.IS_SYNTHESIZED to "/* synthesized */",
Flags.Property.IS_CONST to "const",
Flags.Property.IS_LATEINIT to "lateinit",
Flags.Property.IS_EXTERNAL to "external",
Flags.Property.IS_DELEGATED to "/* delegated */",
Flags.Property.IS_EXPECT to "expect"
)
private val PROPERTY_ACCESSOR_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flags.PropertyAccessor.IS_NOT_DEFAULT to "/* non-default */",
Flags.PropertyAccessor.IS_EXTERNAL to "external",
Flags.PropertyAccessor.IS_INLINE to "inline"
)
private val VALUE_PARAMETER_FLAGS_MAP = mapOf(
Flags.ValueParameter.IS_CROSSINLINE to "crossinline",
Flags.ValueParameter.IS_NOINLINE to "noinline"
)
private val TYPE_PARAMETER_FLAGS_MAP = mapOf(
Flags.TypeParameter.IS_REIFIED to "reified"
)
private val TYPE_FLAGS_MAP = mapOf(
Flags.Type.IS_SUSPEND to "suspend"
)
@@ -0,0 +1,79 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp
import kotlinx.metadata.jvm.KotlinClassHeader
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.Opcodes
import java.io.File
import java.io.FileInputStream
internal fun File.readKotlinClassHeader(): KotlinClassHeader? {
var header: KotlinClassHeader? = null
try {
ClassReader(FileInputStream(this)).accept(object : ClassVisitor(Opcodes.ASM4) {
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? =
if (desc == "Lkotlin/Metadata;") readMetadataVisitor { header = it }
else null
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
} catch (e: Exception) {
return null
}
return header
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
private fun readMetadataVisitor(output: (KotlinClassHeader) -> Unit): AnnotationVisitor =
object : AnnotationVisitor(Opcodes.ASM4) {
var kind: Int? = null
var metadataVersion: IntArray? = null
var bytecodeVersion: IntArray? = null
var data1: Array<String>? = null
var data2: Array<String>? = null
var extraString: String? = null
var packageName: String? = null
var extraInt: Int? = null
override fun visit(name: String?, value: Any?) {
when (name) {
Metadata::k.name -> kind = value as? Int
Metadata::mv.name -> metadataVersion = value as? IntArray
Metadata::bv.name -> bytecodeVersion = value as? IntArray
Metadata::xs.name -> extraString = value as? String
Metadata::xi.name -> extraInt = value as? Int
Metadata::pn.name -> packageName = value as? String
}
}
override fun visitArray(name: String?): AnnotationVisitor? =
when (name) {
Metadata::d1.name -> stringArrayVisitor { data1 = it }
Metadata::d2.name -> stringArrayVisitor { data2 = it }
else -> null
}
private fun stringArrayVisitor(output: (Array<String>) -> Unit): AnnotationVisitor {
return object : AnnotationVisitor(Opcodes.ASM4) {
val strings = mutableListOf<String>()
override fun visit(name: String?, value: Any?) {
(value as? String)?.let(strings::add)
}
override fun visitEnd() {
output(strings.toTypedArray())
}
}
}
override fun visitEnd() {
output(KotlinClassHeader(kind, metadataVersion, bytecodeVersion, data1, data2, extraString, packageName, extraInt))
}
}
@@ -0,0 +1,15 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp.test
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
import java.io.File
abstract class AbstractKotlinpTest : TestCaseWithTmpdir() {
protected fun doTest(fileName: String) {
compileAndPrintAllFiles(File(fileName), testRootDisposable, tmpdir, compareWithTxt = true)
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp.test
import org.jetbrains.kotlin.generators.tests.generator.testGroup
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
testGroup("libraries/tools/kotlinp/test", "libraries/tools/kotlinp/testData") {
testClass<AbstractKotlinpTest> {
model("")
}
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp.test;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("libraries/tools/kotlinp/testData")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class KotlinpTestGenerated extends AbstractKotlinpTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInTestData() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("libraries/tools/kotlinp/testData"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("Annotations.kt")
public void testAnnotations() throws Exception {
runTest("libraries/tools/kotlinp/testData/Annotations.kt");
}
@TestMetadata("Lambda.kt")
public void testLambda() throws Exception {
runTest("libraries/tools/kotlinp/testData/Lambda.kt");
}
@TestMetadata("LocalClass.kt")
public void testLocalClass() throws Exception {
runTest("libraries/tools/kotlinp/testData/LocalClass.kt");
}
@TestMetadata("MultiFileClass.kt")
public void testMultiFileClass() throws Exception {
runTest("libraries/tools/kotlinp/testData/MultiFileClass.kt");
}
@TestMetadata("NestedClasses.kt")
public void testNestedClasses() throws Exception {
runTest("libraries/tools/kotlinp/testData/NestedClasses.kt");
}
@TestMetadata("PlatformType.kt")
public void testPlatformType() throws Exception {
runTest("libraries/tools/kotlinp/testData/PlatformType.kt");
}
@TestMetadata("SimpleClass.kt")
public void testSimpleClass() throws Exception {
runTest("libraries/tools/kotlinp/testData/SimpleClass.kt");
}
@TestMetadata("SimplePackage.kt")
public void testSimplePackage() throws Exception {
runTest("libraries/tools/kotlinp/testData/SimplePackage.kt");
}
@TestMetadata("SyntheticClass.kt")
public void testSyntheticClass() throws Exception {
runTest("libraries/tools/kotlinp/testData/SyntheticClass.kt");
}
@TestMetadata("TypeParameters.kt")
public void testTypeParameters() throws Exception {
runTest("libraries/tools/kotlinp/testData/TypeParameters.kt");
}
@TestMetadata("VersionRequirement.kt")
public void testVersionRequirement() throws Exception {
runTest("libraries/tools/kotlinp/testData/VersionRequirement.kt");
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.kotlinp.test
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.checkers.setupLanguageVersionSettingsForCompilerTests
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.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
import java.io.File
import kotlin.test.fail
fun compileAndPrintAllFiles(file: File, disposable: Disposable, tmpdir: File, compareWithTxt: Boolean) {
val sb = StringBuilder()
compile(file, disposable, tmpdir) { outputFile ->
when (outputFile.extension) {
"kotlin_module" -> {
// TODO: support kotlin_module files
}
"class" -> {
sb.appendFileName(outputFile.relativeTo(tmpdir))
sb.append(Kotlinp.renderClassFile(Kotlinp.readClassFile(outputFile)!!))
}
else -> fail("Unknown file: $outputFile")
}
}
if (compareWithTxt) {
KotlinTestUtils.assertEqualsToFile(File(file.path.replace(".kt", ".txt")), sb.toString())
}
}
private fun compile(file: File, disposable: Disposable, tmpdir: File, forEachOutputFile: (File) -> Unit) {
val environment = KotlinCoreEnvironment.createForTests(
disposable,
KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
setupLanguageVersionSettingsForCompilerTests(file.readText(), environment)
val ktFile = KotlinTestUtils.createFile(file.name, file.readText(), environment.project)
GenerationUtils.compileFileTo(ktFile, environment, tmpdir)
for (outputFile in tmpdir.walkTopDown().sortedBy { it.nameWithoutExtension }) {
if (outputFile.isFile) {
forEachOutputFile(outputFile)
}
}
}
private fun StringBuilder.appendFileName(file: File) {
appendln("// $file")
appendln("// ------------------------------------------")
}
+52
View File
@@ -0,0 +1,52 @@
import kotlin.reflect.KClass
@Target(AnnotationTarget.TYPE)
annotation class A(
val z: Boolean,
val c: Char,
val b: Byte,
val s: Short,
val i: Int,
val f: Float,
val j: Long,
val d: Double,
val za: BooleanArray,
val ca: CharArray,
val ba: ByteArray,
val sa: ShortArray,
val ia: IntArray,
val fa: FloatArray,
val ja: LongArray,
val da: DoubleArray,
val str: String,
val enum: AnnotationTarget,
val klass: KClass<*>,
val anno: B
)
annotation class B(val value: String)
class C {
fun typeAnnotation(): @A(
true,
'x',
1.toByte(),
42.toShort(),
42424242,
-2.72f,
239239239239239L,
3.14,
[true],
['\''],
[1.toByte()],
[42.toShort()],
[42424242],
[-2.72f],
[239239239239239L],
[3.14],
"aba\ncaba'\"\t\u0001\u0002\uA66E",
AnnotationTarget.CLASS,
C::class,
B(value = "aba\ncaba'\"\t\u0001\u0002\uA66E")
) Unit {}
}
+108
View File
@@ -0,0 +1,108 @@
// A.class
// ------------------------------------------
public final annotation class A : kotlin/Annotation {
// signature: <init>(ZCBSIFJD[Z[C[B[S[I[F[J[DLjava/lang/String;Lkotlin/annotation/AnnotationTarget;Lkotlin/reflect/KClass;LB;)V
public /* primary */ constructor(z: kotlin/Boolean, c: kotlin/Char, b: kotlin/Byte, s: kotlin/Short, i: kotlin/Int, f: kotlin/Float, j: kotlin/Long, d: kotlin/Double, za: kotlin/BooleanArray, ca: kotlin/CharArray, ba: kotlin/ByteArray, sa: kotlin/ShortArray, ia: kotlin/IntArray, fa: kotlin/FloatArray, ja: kotlin/LongArray, da: kotlin/DoubleArray, str: kotlin/String, enum: kotlin/annotation/AnnotationTarget, klass: kotlin/reflect/KClass<*>, anno: B)
// field: anno:LB;
public final val anno: B
public final get
// field: b:B
public final val b: kotlin/Byte
public final get
// field: ba:[B
public final val ba: kotlin/ByteArray
public final get
// field: c:C
public final val c: kotlin/Char
public final get
// field: ca:[C
public final val ca: kotlin/CharArray
public final get
// field: d:D
public final val d: kotlin/Double
public final get
// field: da:[D
public final val da: kotlin/DoubleArray
public final get
// field: enum:Lkotlin/annotation/AnnotationTarget;
public final val enum: kotlin/annotation/AnnotationTarget
public final get
// field: f:F
public final val f: kotlin/Float
public final get
// field: fa:[F
public final val fa: kotlin/FloatArray
public final get
// field: i:I
public final val i: kotlin/Int
public final get
// field: ia:[I
public final val ia: kotlin/IntArray
public final get
// field: j:J
public final val j: kotlin/Long
public final get
// field: ja:[J
public final val ja: kotlin/LongArray
public final get
// field: klass:Lkotlin/reflect/KClass;
public final val klass: kotlin/reflect/KClass<*>
public final get
// field: s:S
public final val s: kotlin/Short
public final get
// field: sa:[S
public final val sa: kotlin/ShortArray
public final get
// field: str:Ljava/lang/String;
public final val str: kotlin/String
public final get
// field: z:Z
public final val z: kotlin/Boolean
public final get
// field: za:[Z
public final val za: kotlin/BooleanArray
public final get
}
// B.class
// ------------------------------------------
public final annotation class B : kotlin/Annotation {
// signature: <init>(Ljava/lang/String;)V
public /* primary */ constructor(value: kotlin/String)
// field: value:Ljava/lang/String;
public final val value: kotlin/String
public final get
}
// C.class
// ------------------------------------------
public final class C : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
// signature: typeAnnotation()V
public final fun typeAnnotation(): @A(z = true, c = 'x', b = 1.toByte(), s = 42.toShort(), i = 42424242, f = -2.72f, j = 239239239239239L, d = 3.14, za = [true], ca = ['\''], ba = [1.toByte()], sa = [42.toShort()], ia = [42424242], fa = [-2.72f], ja = [239239239239239L], da = [3.14], str = "aba\ncaba'\"\t\u0001\u0002ꙮ", enum = kotlin/annotation/AnnotationTarget.CLASS, klass = C::class, anno = B(value = "aba\ncaba'\"\t\u0001\u0002ꙮ")) kotlin/Unit
}
+4
View File
@@ -0,0 +1,4 @@
fun test() {
val f = {}
val g = fun Unit.(s: IntArray?, t: Set<Double>): String { return "" }
}
+21
View File
@@ -0,0 +1,21 @@
// LambdaKt.class
// ------------------------------------------
package {
// signature: test()V
public final fun test(): kotlin/Unit
}
// LambdaKt$test$f$1.class
// ------------------------------------------
lambda {
// signature: invoke()V
local final fun <anonymous>(): kotlin/Unit
}
// LambdaKt$test$g$1.class
// ------------------------------------------
lambda {
// signature: invoke(Lkotlin/Unit;[ILjava/util/Set;)Ljava/lang/String;
local final fun kotlin/Unit.<no name provided>(s: kotlin/IntArray?, t: kotlin/collections/Set<kotlin/Double>): kotlin/String
}
+9
View File
@@ -0,0 +1,9 @@
class A {
init {
class L<T> {
inner class I
fun x(l: L<I>) {}
}
}
}
+26
View File
@@ -0,0 +1,26 @@
// A.class
// ------------------------------------------
public final class A : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
}
// A$L.class
// ------------------------------------------
local final class .A$L<T#0 /* T */> : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
// signature: x(LA$L;)V
public final fun x(l: .A$L<.A$L<T#0>.I>): kotlin/Unit
// nested class: I
}
// A$L$I.class
// ------------------------------------------
local final inner class .A$L.I : kotlin/Any {
// signature: <init>(LA$L;)V
public /* primary */ constructor()
}
+5
View File
@@ -0,0 +1,5 @@
@file:JvmMultifileClass
@file:JvmName("File")
package test
const val x = 42
+14
View File
@@ -0,0 +1,14 @@
// test/File.class
// ------------------------------------------
multi-file class {
// test/File__MultiFileClassKt
}
// test/File__MultiFileClassKt.class
// ------------------------------------------
package {
// facade: test/File
// field: x:I
public final const val x: kotlin/Int /* = ... */
public final get
}
+16
View File
@@ -0,0 +1,16 @@
interface A {
interface B {
interface C
}
companion object D {
enum class E {
E1,
E2,
}
sealed class F {
class G : F()
}
}
}
+60
View File
@@ -0,0 +1,60 @@
// A.class
// ------------------------------------------
public abstract interface A : kotlin/Any {
// companion object: D
// nested class: B
// nested class: D
}
// A$B.class
// ------------------------------------------
public abstract interface A.B : kotlin/Any {
// nested class: C
}
// A$B$C.class
// ------------------------------------------
public abstract interface A.B.C : kotlin/Any {
}
// A$D.class
// ------------------------------------------
public final companion object A.D : kotlin/Any {
// signature: <init>()V
private /* primary */ constructor()
// nested class: E
// nested class: F
}
// A$D$E.class
// ------------------------------------------
public final enum class A.D.E : kotlin/Enum<A.D.E> {
// signature: <init>(Ljava/lang/String;I)V
private /* primary */ constructor()
E1,
E2,
}
// A$D$F.class
// ------------------------------------------
public sealed class A.D.F : kotlin/Any {
// signature: <init>()V
private /* primary */ constructor()
// nested class: G
// sealed subclass: A.D.F.G
}
// A$D$F$G.class
// ------------------------------------------
public final class A.D.F.G : A.D.F {
// signature: <init>()V
public /* primary */ constructor()
}
+7
View File
@@ -0,0 +1,7 @@
import java.io.File
class PlatformType {
fun nullability() = File(".").absoluteFile
fun mutability() = File(".").toURI().toURL().openConnection().headerFields
}
+13
View File
@@ -0,0 +1,13 @@
// PlatformType.class
// ------------------------------------------
public final class PlatformType : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
// signature: mutability()Ljava/util/Map;
public final fun mutability(): kotlin/collections/MutableMap<kotlin/String!, kotlin/collections/MutableList<kotlin/String!>..kotlin/collections/List<kotlin/String!>?>..kotlin/collections/Map<kotlin/String!, kotlin/collections/MutableList<kotlin/String!>..kotlin/collections/List<kotlin/String!>?>?
// signature: nullability()Ljava/io/File;
public final fun nullability(): java/io/File!
}
+13
View File
@@ -0,0 +1,13 @@
class SimpleClass<in A>(val p: Int = 42) {
constructor(s: Array<String?>?) : this(s?.size ?: 0)
var x: Long = p.toLong()
external get
@JvmName("SET_X") set
internal fun <U : A, V, A> A.f(vararg z: Map<V, U?>): Set<*> where V : A {
error("")
}
protected suspend inline fun <reified T> g(crossinline a: () -> A, noinline b: suspend () -> T) {}
}
+29
View File
@@ -0,0 +1,29 @@
// SimpleClass.class
// ------------------------------------------
public final class SimpleClass<in T#0 /* A */> : kotlin/Any {
// signature: <init>([Ljava/lang/String;)V
public constructor(s: kotlin/Array<kotlin/String?>?)
// signature: <init>(I)V
public /* primary */ constructor(p: kotlin/Int /* = ... */)
// requires language version 1.1.0 (level=ERROR)
// signature: g(Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
protected final inline suspend fun <reified T#1 /* T */> g(crossinline a: kotlin/Function0<T#0>, noinline b: suspend kotlin/Function1<kotlin/coroutines/experimental/Continuation<T#1>, kotlin/Any?>): kotlin/Unit
// signature: f$test_module(Ljava/lang/Object;[Ljava/util/Map;)Ljava/util/Set;
internal final fun <T#1 /* U */ : T#3, T#2 /* V */ : T#3, T#3 /* A */> T#3.f(vararg z: kotlin/collections/Map<T#2, T#1?> /* kotlin/Array<out kotlin/collections/Map<T#2, T#1?>> */): kotlin/collections/Set<*>
// field: p:I
// getter: getP()I
public final val p: kotlin/Int
public final get
// field: x:J
// getter: getX()J
// setter: SET_X(J)V
public final var x: kotlin/Long
public final /* non-default */ external get
public final /* non-default */ set(<set-?>: kotlin/Long)
}
+8
View File
@@ -0,0 +1,8 @@
internal inline fun <reified X : Any> topLevelFun(x: X) = X::class
var topLevelProp: String? = null
private set
typealias F<T, U> = Map<T, (StringBuilder) -> U?>
typealias G<S> = F<List<S>, Set<S>>
+18
View File
@@ -0,0 +1,18 @@
// SimplePackageKt.class
// ------------------------------------------
package {
// signature: topLevelFun(Ljava/lang/Object;)Lkotlin/reflect/KClass;
internal final inline fun <reified T#0 /* X */ : kotlin/Any> topLevelFun(x: T#0): kotlin/reflect/KClass<T#0>
// field: topLevelProp:Ljava/lang/String;
// getter: getTopLevelProp()Ljava/lang/String;
// setter: setTopLevelProp(Ljava/lang/String;)V
public final var topLevelProp: kotlin/String?
public final get
private final /* non-default */ set(<set-?>: kotlin/String?)
public typealias F<T#0 /* T */, T#1 /* U */> = kotlin/collections/Map<T#0, kotlin/Function1<kotlin/text/StringBuilder^, T#1?>> /* = kotlin/collections/Map<T#0, kotlin/Function1<java/lang/StringBuilder /* = kotlin/text/StringBuilder^ */, T#1?>> */
public typealias G<T#0 /* S */> = F^<kotlin/collections/List<T#0>, kotlin/collections/Set<T#0>> /* = kotlin/collections/Map<kotlin/collections/List<T#0>, kotlin/Function1<java/lang/StringBuilder /* = kotlin/text/StringBuilder^ */, kotlin/collections/Set<T#0>?>> */
}
+7
View File
@@ -0,0 +1,7 @@
fun f(a: AnnotationTarget): String? {
return when (a) {
AnnotationTarget.FUNCTION -> "1"
AnnotationTarget.PROPERTY -> "2"
else -> null
}
}
+10
View File
@@ -0,0 +1,10 @@
// SyntheticClassKt.class
// ------------------------------------------
package {
// signature: f(Lkotlin/annotation/AnnotationTarget;)Ljava/lang/String;
public final fun f(a: kotlin/annotation/AnnotationTarget): kotlin/String?
}
// SyntheticClassKt$WhenMappings.class
// ------------------------------------------
synthetic class
+17
View File
@@ -0,0 +1,17 @@
class A<T> {
fun <T> a(t: T) {}
inner class B<U, V : U> {
fun <T, U> b(t: T, u: U, v: V) where T : Comparable<T>, T : Cloneable {}
fun bb(t: T) {}
inner class C<T, U> {
fun <T, U> c(t: T?, u: U?) {}
fun cc(t: T?, u: U?) {}
fun z(c: A<Int>.B<Any, Byte>.C<Unit, Long>) {}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
// A.class
// ------------------------------------------
public final class A<T#0 /* T */> : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
// signature: a(Ljava/lang/Object;)V
public final fun <T#1 /* T */> a(t: T#1): kotlin/Unit
// nested class: B
}
// A$B.class
// ------------------------------------------
public final inner class A.B<T#1 /* U */, T#2 /* V */ : T#1> : kotlin/Any {
// signature: <init>(LA;)V
public /* primary */ constructor()
// signature: b(Ljava/lang/Comparable;Ljava/lang/Object;Ljava/lang/Object;)V
public final fun <T#3 /* T */ : kotlin/Comparable<T#3> & kotlin/Cloneable, T#4 /* U */> b(t: T#3, u: T#4, v: T#2): kotlin/Unit
// signature: bb(Ljava/lang/Object;)V
public final fun bb(t: T#0): kotlin/Unit
// nested class: C
}
// A$B$C.class
// ------------------------------------------
public final inner class A.B.C<T#3 /* T */, T#4 /* U */> : kotlin/Any {
// signature: <init>(LA$B;)V
public /* primary */ constructor()
// signature: c(Ljava/lang/Object;Ljava/lang/Object;)V
public final fun <T#5 /* T */, T#6 /* U */> c(t: T#5?, u: T#6?): kotlin/Unit
// signature: cc(Ljava/lang/Object;Ljava/lang/Object;)V
public final fun cc(t: T#3?, u: T#4?): kotlin/Unit
// signature: z(LA$B$C;)V
public final fun z(c: A<kotlin/Int>.B<kotlin/Any, kotlin/Byte>.C<kotlin/Unit, kotlin/Long>): kotlin/Unit
}
+19
View File
@@ -0,0 +1,19 @@
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
package test
import kotlin.internal.RequireKotlin
import kotlin.internal.RequireKotlinVersionKind
@RequireKotlin("1.2", "Klass must not be used!", DeprecationLevel.WARNING, RequireKotlinVersionKind.API_VERSION)
class Klass
class Konstructor @RequireKotlin("42.0", "Konstructor must not be used!", DeprecationLevel.WARNING, RequireKotlinVersionKind.LANGUAGE_VERSION, 42) constructor()
@RequireKotlin("1.1", level = DeprecationLevel.HIDDEN, versionKind = RequireKotlinVersionKind.API_VERSION, errorCode = 314)
typealias Typealias = String
@RequireKotlin("1.2.40", level = DeprecationLevel.ERROR, versionKind = RequireKotlinVersionKind.COMPILER_VERSION)
fun function() {}
@RequireKotlin("1.3", "property must not be used!")
val property = ""
+34
View File
@@ -0,0 +1,34 @@
// test/Klass.class
// ------------------------------------------
// requires API version 1.2.0 (level=WARNING, message="Klass must not be used!")
public final class test/Klass : kotlin/Any {
// signature: <init>()V
public /* primary */ constructor()
}
// test/Konstructor.class
// ------------------------------------------
public final class test/Konstructor : kotlin/Any {
// requires language version 42.0.0 (level=WARNING, errorCode=42, message="Konstructor must not be used!")
// signature: <init>()V
public /* primary */ constructor()
}
// test/VersionRequirementKt.class
// ------------------------------------------
package {
// requires compiler version 1.2.40 (level=ERROR)
// signature: function()V
public final fun function(): kotlin/Unit
// requires language version 1.3.0 (level=ERROR, message="property must not be used!")
// field: property:Ljava/lang/String;
// getter: getProperty()Ljava/lang/String;
// synthetic method for annotations: property$annotations()V
public final val property: kotlin/String /* = ... */
public final get
// requires API version 1.1.0 (level=HIDDEN, errorCode=314)
public typealias Typealias = kotlin/String /* = kotlin/String */
}
+2
View File
@@ -134,6 +134,7 @@ include ":kotlin-build-common",
":tools:binary-compatibility-validator",
":tools:kotlin-stdlib-js-merger",
":tools:kotlin-stdlib-gen",
":tools:kotlinp",
":kotlin-gradle-plugin-api",
":kotlin-gradle-plugin",
":kotlin-gradle-plugin-test-utils-embeddable",
@@ -240,6 +241,7 @@ project(':kotlin-source-sections-compiler-plugin').projectDir = "$rootDir/plugin
project(':tools:binary-compatibility-validator').projectDir = "$rootDir/libraries/tools/binary-compatibility-validator" as File
project(':tools:kotlin-stdlib-js-merger').projectDir = "$rootDir/libraries/tools/kotlin-stdlib-js-merger" as File
project(':tools:kotlin-stdlib-gen').projectDir = "$rootDir/libraries/tools/kotlin-stdlib-gen" as File
project(':tools:kotlinp').projectDir = "$rootDir/libraries/tools/kotlinp" as File
project(':kotlin-gradle-plugin-api').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-api" as File
project(':kotlin-gradle-plugin').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin" as File
project(':kotlin-gradle-plugin-test-utils-embeddable').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-test-utils-embeddable" as File