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:
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
+18
@@ -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("")
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,4 @@
|
||||
fun test() {
|
||||
val f = {}
|
||||
val g = fun Unit.(s: IntArray?, t: Set<Double>): String { return "" }
|
||||
}
|
||||
+21
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
init {
|
||||
class L<T> {
|
||||
inner class I
|
||||
|
||||
fun x(l: L<I>) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("File")
|
||||
package test
|
||||
|
||||
const val x = 42
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
interface A {
|
||||
interface B {
|
||||
interface C
|
||||
}
|
||||
|
||||
companion object D {
|
||||
enum class E {
|
||||
E1,
|
||||
E2,
|
||||
}
|
||||
|
||||
sealed class F {
|
||||
class G : F()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.io.File
|
||||
|
||||
class PlatformType {
|
||||
fun nullability() = File(".").absoluteFile
|
||||
|
||||
fun mutability() = File(".").toURI().toURL().openConnection().headerFields
|
||||
}
|
||||
@@ -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
@@ -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) {}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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>>
|
||||
@@ -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>?>> */
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun f(a: AnnotationTarget): String? {
|
||||
return when (a) {
|
||||
AnnotationTarget.FUNCTION -> "1"
|
||||
AnnotationTarget.PROPERTY -> "2"
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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>) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 = ""
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user