Kapt: Do not use awkward ('$' -> '/') logic for KAPT3 class builder mode

So (for the most often reproduction case) #KT-19433 Fixed

Before this commit, internal names for nested classes were written as test/Foo/Bar (comparing to test/Foo$Bar in the normal mode), as getting qualified names from such internal names was trivial. But, because of IC, we needed to write class files to the disk, so our decompiler could find such "broken" classes and read it in a wrong way.
This commit is contained in:
Yan Zhulanow
2017-08-11 17:36:28 +05:00
committed by Mikhail Glukhikh
parent e5e5b56af0
commit 57d209f599
18 changed files with 708 additions and 83 deletions
@@ -99,20 +99,6 @@ public class KotlinTypeMapper {
private final boolean isJvm8TargetWithDefaults;
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
private final Function2<String, String, String> defaultClassNameFactory
= TypeMappingConfiguration.Companion.getDEFAULT_INNER_CLASS_NAME_FACTORY();
private final Function2<String, String, String> innerClassNameFactory = new Function2<String, String, String>() {
@Override
public String invoke(String outer, String inner) {
if (classBuilderMode == ClassBuilderMode.KAPT3) {
return outer + '/' + inner;
}
return defaultClassNameFactory.invoke(outer, inner);
}
};
@NotNull
@Override
public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
@@ -122,7 +108,7 @@ public class KotlinTypeMapper {
@NotNull
@Override
public Function2<String, String, String> getInnerClassNameFactory() {
return innerClassNameFactory;
return TypeMappingConfiguration.DefaultImpls.getInnerClassNameFactory(this);
}
@Nullable
+32 -32
View File
@@ -1,23 +1,6 @@
@kotlin.Metadata
public final class test/TopLevel {
public final static field Companion: test.TopLevel.Companion
private final static @org.jetbrains.annotations.NotNull field q: java.lang.String
private final @org.jetbrains.annotations.NotNull field x: java.lang.String
private final field y: int
inner class test/TopLevel/Companion
inner class test/TopLevel/InnerInterface
inner class test/TopLevel/InnerObject
inner class test/TopLevel/NestedClass
public method <init>(): void
public final method b(): void
public final static @org.jetbrains.annotations.NotNull method getQ(): java.lang.String
public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String
public final method getY(): int
}
@kotlin.Metadata
public final class test/TopLevel/Companion {
inner class test/TopLevel/Companion
public final class test/TopLevel$Companion {
inner class test/TopLevel$Companion
private method <init>(): void
public final method a(): void
public final @org.jetbrains.annotations.NotNull method getQ(): java.lang.String
@@ -25,28 +8,45 @@ public final class test/TopLevel/Companion {
}
@kotlin.Metadata
public interface test/TopLevel/InnerInterface {
inner class test/TopLevel/InnerInterface
public interface test/TopLevel$InnerInterface {
inner class test/TopLevel$InnerInterface
}
@kotlin.Metadata
public final class test/TopLevel/InnerObject {
public final static field INSTANCE: test.TopLevel.InnerObject
inner class test/TopLevel/InnerObject
public final class test/TopLevel$InnerObject {
public final static field INSTANCE: test.TopLevel$InnerObject
inner class test/TopLevel$InnerObject
private method <init>(): void
}
@kotlin.Metadata
public final class test/TopLevel/NestedClass {
inner class test/TopLevel/NestedClass
inner class test/TopLevel/NestedClass/NestedInnerClass
public final class test/TopLevel$NestedClass$NestedInnerClass {
synthetic final field this$0: test.TopLevel$NestedClass
inner class test/TopLevel$NestedClass
inner class test/TopLevel$NestedClass$NestedInnerClass
public method <init>(p0: test.TopLevel$NestedClass): void
}
@kotlin.Metadata
public final class test/TopLevel$NestedClass {
inner class test/TopLevel$NestedClass
inner class test/TopLevel$NestedClass$NestedInnerClass
public method <init>(): void
}
@kotlin.Metadata
public final class test/TopLevel/NestedClass/NestedInnerClass {
synthetic final field this$0: test.TopLevel.NestedClass
inner class test/TopLevel/NestedClass
inner class test/TopLevel/NestedClass/NestedInnerClass
public method <init>(p0: test.TopLevel.NestedClass): void
public final class test/TopLevel {
public final static field Companion: test.TopLevel$Companion
private final static @org.jetbrains.annotations.NotNull field q: java.lang.String
private final @org.jetbrains.annotations.NotNull field x: java.lang.String
private final field y: int
inner class test/TopLevel$Companion
inner class test/TopLevel$InnerInterface
inner class test/TopLevel$InnerObject
inner class test/TopLevel$NestedClass
public method <init>(): void
public final method b(): void
public final static @org.jetbrains.annotations.NotNull method getQ(): java.lang.String
public final @org.jetbrains.annotations.NotNull method getX(): java.lang.String
public final method getY(): int
}
+7 -7
View File
@@ -1,14 +1,14 @@
@kotlin.Metadata
public interface A {
inner class A/DefaultImpls
public abstract method a(): void
public abstract method b(): void
public final class A$DefaultImpls {
inner class A$DefaultImpls
public static method a(p0: A): void
}
@kotlin.Metadata
public final class A/DefaultImpls {
inner class A/DefaultImpls
public static method a(p0: A): void
public interface A {
inner class A$DefaultImpls
public abstract method a(): void
public abstract method b(): void
}
@kotlin.Metadata
@@ -47,8 +47,8 @@ private fun <T : Any> JvmTypeFactory<T>.boxTypeIfNeeded(possiblyPrimitiveType: T
if (needBoxedType) boxType(possiblyPrimitiveType) else possiblyPrimitiveType
interface TypeMappingConfiguration<out T : Any> {
companion object {
val DEFAULT_INNER_CLASS_NAME_FACTORY = fun(outer: String, inner: String) = outer + "$" + inner
private companion object {
private val DEFAULT_INNER_CLASS_NAME_FACTORY = fun(outer: String, inner: String) = outer + "$" + inner
}
val innerClassNameFactory: (outer: String, inner: String) -> String
@@ -186,7 +186,7 @@ abstract class AbstractKapt3Extension(
private fun generateStubs(project: Project, module: ModuleDescriptor, context: BindingContext, files: Collection<KtFile>): KaptContext<*> {
if (!aptMode.generateStubs) {
return KaptContext(logger, BindingContext.EMPTY, emptyList(), emptyMap(), null, options, javacOptions)
return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null, options, javacOptions)
}
logger.info { "Kotlin files to compile: " + files.map { it.virtualFile?.name ?: "<in memory ${it.hashCode()}>" } }
@@ -241,7 +241,7 @@ abstract class AbstractKapt3Extension(
logger.info { "Stubs compilation took $classFilesCompilationTime ms" }
logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } }
return KaptContext(logger, bindingContext, compiledClasses, origins, generationState, options, javacOptions)
return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState, options, javacOptions)
}
private fun generateKotlinSourceStubs(kaptContext: KaptContext<GenerationState>) {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.kapt3
import com.intellij.openapi.project.Project
import com.sun.tools.javac.file.JavacFileManager
import com.sun.tools.javac.jvm.ClassReader
import com.sun.tools.javac.main.JavaCompiler
@@ -34,6 +35,7 @@ import javax.tools.JavaFileManager
class KaptContext<out GState : GenerationState?>(
val logger: KaptLogger,
val project: Project,
val bindingContext: BindingContext,
val compiledClasses: List<ClassNode>,
val origins: Map<Any, JvmDeclarationOrigin>,
@@ -50,7 +52,7 @@ class KaptContext<out GState : GenerationState?>(
init {
KaptJavaLog.preRegister(context, logger.messageCollector)
JavacFileManager.preRegister(context)
KaptTreeMaker.preRegister(context)
KaptTreeMaker.preRegister(context, this)
KaptJavaCompiler.preRegister(context)
fileManager = context.get(JavaFileManager::class.java) as JavacFileManager
@@ -16,28 +16,34 @@
package org.jetbrains.kotlin.kapt3.javac
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import com.sun.tools.javac.code.TypeTag
import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.tree.TreeMaker
import com.sun.tools.javac.util.Context
import com.sun.tools.javac.util.Name
import com.sun.tools.javac.util.Names
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.kapt3.KaptContext
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type.*
import org.jetbrains.org.objectweb.asm.tree.ClassNode
class KaptTreeMaker(context: Context) : TreeMaker(context) {
val nameTable = Names.instance(context).table
class KaptTreeMaker(context: Context, private val kaptContext: KaptContext<*>) : TreeMaker(context) {
val nameTable: Name.Table = Names.instance(context).table
fun Type(type: Type): JCTree.JCExpression {
convertBuiltinType(type)?.let { return it }
if (type.sort == ARRAY) {
return TypeArray(Type(AsmUtil.correctElementType(type)))
}
return FqName(type.className)
return FqName(type.internalName)
}
fun FqName(internalOrFqName: String): JCTree.JCExpression {
val path = internalOrFqName.replace('/', '.').convertSpecialFqName().split('.')
val path = getQualifiedName(internalOrFqName.replace('/', '.')).convertSpecialFqName().split('.')
assert(path.isNotEmpty())
if (path.size == 1) return SimpleName(path.single())
@@ -48,6 +54,74 @@ class KaptTreeMaker(context: Context) : TreeMaker(context) {
return expr
}
fun getQualifiedName(type: Type) = getQualifiedName(type.internalName)
fun getSimpleName(clazz: ClassNode) = getQualifiedName(clazz.name).substringAfterLast('.')
fun getQualifiedName(internalName: String): String {
val nameWithDots = internalName.replace('/', '.')
// This is a top-level class
if ('$' !in nameWithDots) return nameWithDots
// Maybe it's in our sources?
val classFromSources = kaptContext.compiledClasses.firstOrNull { it.name == internalName }
if (classFromSources != null) {
// Get inner class node pointing to the outer class
val innerClassNode = classFromSources.innerClasses.firstOrNull { it.name == classFromSources.name }
return innerClassNode?.let { getQualifiedName(it.outerName) + "." + it.innerName } ?: nameWithDots
}
// Search in the classpath
val javaPsiFacade = JavaPsiFacade.getInstance(kaptContext.project)
val scope = GlobalSearchScope.allScope(javaPsiFacade.project)
val fqNameFromClassWithPreciseName = javaPsiFacade.findClass(nameWithDots, scope)?.qualifiedName
if (fqNameFromClassWithPreciseName != null) {
return fqNameFromClassWithPreciseName
}
nameWithDots.iterateDollars { outerName, innerName ->
if (innerName.isEmpty()) return@iterateDollars // We already checked an exact match
val outerClass = javaPsiFacade.findClass(outerName, scope) ?: return@iterateDollars
return tryToFindNestedClass(outerClass, innerName)?.qualifiedName ?: return@iterateDollars
}
return nameWithDots
}
private fun tryToFindNestedClass(outerClass: PsiClass, innerClassName: String): PsiClass? {
outerClass.findInnerClassByName(innerClassName, false)?.let { return it }
innerClassName.iterateDollars { name1, name2 ->
if (name2.isEmpty()) return outerClass.findInnerClassByName(name1, false)
val nestedClass = outerClass.findInnerClassByName(name1, false)
if (nestedClass != null) {
tryToFindNestedClass(nestedClass, name2)?.let { return it }
}
}
return null
}
private inline fun String.iterateDollars(variantHandler: (outerName: String, innerName: String) -> Unit) {
var dollarIndex = this.indexOf('$')
if (dollarIndex < 0) {
variantHandler(this, "")
return
}
while (dollarIndex > 0 && dollarIndex < this.lastIndex) {
val outerName = this.take(dollarIndex)
val innerName = this.drop(dollarIndex + 1)
variantHandler(outerName, innerName)
dollarIndex = this.indexOf('$', startIndex = dollarIndex + 1)
}
}
private fun String.convertSpecialFqName(): String {
// Hard-coded in ImplementationBodyCodegen, KOTLIN_MARKER_INTERFACES
if (this == "kotlin.jvm.internal.markers.KMutableMap\$Entry") {
@@ -57,7 +131,7 @@ class KaptTreeMaker(context: Context) : TreeMaker(context) {
return this
}
fun convertBuiltinType(type: Type): JCTree.JCExpression? {
private fun convertBuiltinType(type: Type): JCTree.JCExpression? {
val typeTag = when (type) {
BYTE_TYPE -> TypeTag.BYTE
BOOLEAN_TYPE -> TypeTag.BOOLEAN
@@ -75,11 +149,11 @@ class KaptTreeMaker(context: Context) : TreeMaker(context) {
fun SimpleName(name: String): JCTree.JCExpression = Ident(name(name))
fun name(name: String) = nameTable.fromString(name)
fun name(name: String): Name = nameTable.fromString(name)
companion object {
internal fun preRegister(context: Context) {
context.put(treeMakerKey, Context.Factory<TreeMaker>(::KaptTreeMaker))
internal fun preRegister(context: Context, kaptContext: KaptContext<*>) {
context.put(treeMakerKey, Context.Factory<TreeMaker> { KaptTreeMaker(it, kaptContext) })
}
}
}
@@ -204,7 +204,7 @@ class ClassFileToSourceStubConverter(
if (isEnum) ElementKind.ENUM else ElementKind.CLASS,
packageFqName, clazz.visibleAnnotations, clazz.invisibleAnnotations)
val isDefaultImpls = clazz.name.endsWith("${descriptor.name.asString()}/DefaultImpls")
val isDefaultImpls = clazz.name.endsWith("${descriptor.name.asString()}\$DefaultImpls")
&& isPublic(clazz.access) && isFinal(clazz.access)
&& descriptor is ClassDescriptor
&& descriptor.kind == ClassKind.INTERFACE
@@ -218,10 +218,10 @@ class ClassFileToSourceStubConverter(
val interfaces = mapJList(clazz.interfaces) {
if (isAnnotation && it == "java/lang/annotation/Annotation") return@mapJList null
treeMaker.FqName(it)
treeMaker.FqName(treeMaker.getQualifiedName(it))
}
val superClass = treeMaker.FqName(clazz.superName)
val superClass = treeMaker.FqName(treeMaker.getQualifiedName(clazz.superName))
val hasSuperClass = clazz.superName != "java/lang/Object" && !isEnum
val genericType = signatureParser.parseClassSignature(clazz.signature, superClass, interfaces)
@@ -322,15 +322,12 @@ class ClassFileToSourceStubConverter(
outerClass: ClassNode? = findContainingClassNode(clazz)
): Boolean {
if (outerClass == null) return false
if (clazz.simpleName == outerClass.simpleName) return true
if (treeMaker.getSimpleName(clazz) == treeMaker.getSimpleName(outerClass)) return true
// Try to find the containing class for outerClassNode (to check the whole tree recursively)
val containingClassForOuterClass = findContainingClassNode(outerClass) ?: return false
return checkIfInnerClassNameConflictsWithOuter(clazz, containingClassForOuterClass)
}
private val ClassNode.simpleName: String
get() = name.substringAfterLast(".").substringAfterLast("/")
private fun getClassAccessFlags(clazz: ClassNode, descriptor: DeclarationDescriptor, isInner: Boolean, isNested: Boolean) = when {
(descriptor.containingDeclaration as? ClassDescriptor)?.kind == ClassKind.INTERFACE -> {
// Classes inside interfaces should always be public and static.
@@ -373,7 +370,7 @@ class ClassFileToSourceStubConverter(
// Enum type must be an identifier (Javac requirement)
val typeExpression = if (isEnum(field.access))
treeMaker.SimpleName(type.className.substringAfterLast('.'))
treeMaker.SimpleName(treeMaker.getQualifiedName(type).substringAfterLast('.'))
else
anonymousTypeHandler.getNonAnonymousType(descriptor) {
getNonErrorType((descriptor as? CallableDescriptor)?.returnType,
@@ -606,7 +603,7 @@ class ClassFileToSourceStubConverter(
private fun convertAnnotation(annotation: AnnotationNode, packageFqName: String? = "", filtered: Boolean = true): JCAnnotation? {
val annotationType = Type.getType(annotation.desc)
val fqName = annotationType.className
val fqName = treeMaker.getQualifiedName(annotationType)
if (filtered) {
if (BLACKLISTED_ANNOTATIONS.any { fqName.startsWith(it) }) return null
@@ -203,7 +203,7 @@ class SignatureParser(val treeMaker: KaptTreeMaker) {
val innerClasses = mutableListOf<SignatureNode>()
node.split(typeArgs, TypeArgument, innerClasses, InnerClass)
var expression = makeExpressionForClassTypeWithArguments(treeMaker.FqName(node.name!!.replace('/', '.')), typeArgs)
var expression = makeExpressionForClassTypeWithArguments(treeMaker.FqName(node.name!!), typeArgs)
if (innerClasses.isEmpty()) return expression
for (innerClass in innerClasses) {
@@ -74,7 +74,7 @@ private fun convertUserType(type: KtUserType, converter: ClassFileToSourceStubCo
// This could be List<SomeErrorType> or similar. List should be converted to java.util.List in this case.
val referenceTarget = converter.kaptContext.bindingContext[BindingContext.REFERENCE_TARGET, type.referenceExpression]
if (referenceTarget is ClassDescriptor) {
treeMaker.FqName(converter.kaptContext.generationState.typeMapper.mapType(referenceTarget.defaultType).className)
treeMaker.FqName(converter.kaptContext.generationState.typeMapper.mapType(referenceTarget.defaultType).internalName)
}
else {
treeMaker.SimpleName(referencedName)
@@ -61,7 +61,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
val generationState = GenerationUtils.compileFiles(myFiles.psiFiles, myEnvironment, classBuilderFactory)
val logger = KaptLogger(isVerbose = true, messageCollector = messageCollector)
val kaptContext = KaptContext(logger, generationState.bindingContext, classBuilderFactory.compiledClasses,
val kaptContext = KaptContext(logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses,
classBuilderFactory.origins, generationState, processorOptions = emptyMap())
try {
check(kaptContext, txtFile, wholeFile)
@@ -228,6 +228,18 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
doTest(fileName);
}
@TestMetadata("nestedClasses2.kt")
public void testNestedClasses2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/nestedClasses2.kt");
doTest(fileName);
}
@TestMetadata("nestedClassesNonRootPackage.kt")
public void testNestedClassesNonRootPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/nestedClassesNonRootPackage.kt");
doTest(fileName);
}
@TestMetadata("nonExistentClass.kt")
public void testNonExistentClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/nonExistentClass.kt");
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.kapt3.test
import com.intellij.openapi.command.impl.DummyProject
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.kapt3.KaptContext
@@ -80,6 +81,7 @@ class JavaKaptContextTest {
private fun doAnnotationProcessing(javaSourceFile: File, processor: Processor, outputDir: File) {
KaptContext(KaptLogger(isVerbose = true, messageCollector = messageCollector),
DummyProject.getInstance(),
bindingContext = BindingContext.EMPTY,
compiledClasses = emptyList(),
origins = emptyMap(),
@@ -52,10 +52,10 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest() {
assert(!File(stubsOutputDir, "test/Simple/InnerClass.java").exists())
assert(File(incrementalDataOutputDir, "test/Simple.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple/Companion.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple/InnerClass.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple/NestedClass.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple/NestedClass/NestedNestedClass.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple\$Companion.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple\$InnerClass.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple\$NestedClass.class").exists())
assert(File(incrementalDataOutputDir, "test/Simple\$NestedClass\$NestedNestedClass.class").exists())
assert(bindings.any { it.key == "test/Simple" && it.value.name == "test/Simple.java" })
assert(bindings.none { it.key.contains("Companion") })
+78
View File
@@ -0,0 +1,78 @@
// FILE: JavaClass.java
public class JavaClass {
public class Foo {
public class Bar {}
}
}
//FILE: J$B.java
public class J$B {
public class C {}
public class D$E {
class F {}
class F$G {}
}
public class D$$E {}
public class D$$$E {}
}
// FILE: a.kt
interface IFoo {
interface IBar {
annotation class Anno(vararg val value: kotlin.reflect.KClass<*>)
@Anno(IZoo::class)
interface IZoo
}
}
class Experiment {
annotation class Type
@Type
data class Group(s: String)
}
class Foo {
open class Bar {
object Zoo
}
}
class `A$B` {
class C
@JvmField lateinit var c: C
@JvmField lateinit var de: `D$E`
@JvmField lateinit var jc: `J$B`.C
@JvmField lateinit var jde: `J$B`.`D$E`
class `D$E` {
class F
class `F$G`
@JvmField lateinit var f: F
@JvmField lateinit var fg: `F$G`
@JvmField lateinit var jf: `J$B`.`D$E`.F
@JvmField lateinit var jfg: `J$B`.`D$E`.`F$G`
}
class `D$$E`
class `D$$$E`
@JvmField lateinit var dee: `D$$E`
@JvmField lateinit var deee: `D$$$E`
@JvmField lateinit var jdee: `J$B`.`D$$E`
@JvmField lateinit var jdeee: `J$B`.`D$$$E`
}
@IFoo.IBar.Anno(IFoo.IBar.IZoo::class, Foo.Bar::class)
class Test1(val zoo: Foo.Bar.Zoo) : Foo.Bar(), IFoo.IBar, IFoo.IBar.IZoo {
fun a(): Thread.State = Thread.State.NEW
fun b(foo: JavaClass.Foo, bar: JavaClass.Foo.Bar) {}
}
+192
View File
@@ -0,0 +1,192 @@
@kotlin.Metadata()
public final class A$B {
@org.jetbrains.annotations.NotNull()
public A$B.C c;
@org.jetbrains.annotations.NotNull()
public A$B.D$E de;
@org.jetbrains.annotations.NotNull()
public J$B.C jc;
@org.jetbrains.annotations.NotNull()
public J$B.D$E jde;
@org.jetbrains.annotations.NotNull()
public A$B.D$$E dee;
@org.jetbrains.annotations.NotNull()
public A$B.D$$$E deee;
@org.jetbrains.annotations.NotNull()
public J$B.D$$E jdee;
@org.jetbrains.annotations.NotNull()
public J$B.D$$$E jdeee;
public A$B() {
super();
}
@kotlin.Metadata()
public static final class C {
public C() {
super();
}
}
@kotlin.Metadata()
public static final class D$E {
@org.jetbrains.annotations.NotNull()
public A$B.D$E.F f;
@org.jetbrains.annotations.NotNull()
public A$B.D$E.F$G fg;
@org.jetbrains.annotations.NotNull()
public J$B.D$E.F jf;
@org.jetbrains.annotations.NotNull()
public J$B.D$E.F$G jfg;
public D$E() {
super();
}
@kotlin.Metadata()
public static final class F {
public F() {
super();
}
}
@kotlin.Metadata()
public static final class F$G {
public F$G() {
super();
}
}
}
@kotlin.Metadata()
public static final class D$$E {
public D$$E() {
super();
}
}
@kotlin.Metadata()
public static final class D$$$E {
public D$$$E() {
super();
}
}
}
////////////////////
@kotlin.Metadata()
public final class Experiment {
public Experiment() {
super();
}
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public static abstract @interface Type {
}
@kotlin.Metadata()
@Experiment.Type()
public static final class Group {
public Group(@org.jetbrains.annotations.NotNull()
java.lang.String s) {
super();
}
@org.jetbrains.annotations.NotNull()
public final Experiment.Group copy(@org.jetbrains.annotations.NotNull()
java.lang.String s) {
return null;
}
}
}
////////////////////
@kotlin.Metadata()
public final class Foo {
public Foo() {
super();
}
@kotlin.Metadata()
public static class Bar {
public Bar() {
super();
}
@kotlin.Metadata()
public static final class Zoo {
public static final Foo.Bar.Zoo INSTANCE = null;
private Zoo() {
super();
}
}
}
}
////////////////////
@kotlin.Metadata()
public abstract interface IFoo {
@kotlin.Metadata()
public static abstract interface IBar {
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public static abstract @interface Anno {
public abstract java.lang.Class<?>[] value();
}
@kotlin.Metadata()
@IFoo.IBar.Anno(value = {IFoo.IBar.IZoo.class})
public static abstract interface IZoo {
}
}
}
////////////////////
@kotlin.Metadata()
@IFoo.IBar.Anno(value = {IFoo.IBar.IZoo.class, Foo.Bar.class})
public final class Test1 extends Foo.Bar implements IFoo.IBar, IFoo.IBar.IZoo {
@org.jetbrains.annotations.NotNull()
private final Foo.Bar.Zoo zoo = null;
@org.jetbrains.annotations.NotNull()
public final java.lang.Thread.State a() {
return null;
}
public final void b(@org.jetbrains.annotations.NotNull()
JavaClass.Foo foo, @org.jetbrains.annotations.NotNull()
JavaClass.Foo.Bar bar) {
}
@org.jetbrains.annotations.NotNull()
public final Foo.Bar.Zoo getZoo() {
return null;
}
public Test1(@org.jetbrains.annotations.NotNull()
Foo.Bar.Zoo zoo) {
super();
}
}
@@ -0,0 +1,84 @@
// FILE: test/JavaClass.java
package test;
class JavaClass {
class Foo {
class Bar {}
}
}
//FILE: test/J$B.java
package test;
public class J$B {
public class C {}
public class D$E {
class F {}
class F$G {}
}
public class D$$E {}
public class D$$$E {}
}
// FILE: a.kt
package test
interface IFoo {
interface IBar {
annotation class Anno(vararg val value: kotlin.reflect.KClass<*>)
@Anno(IZoo::class)
interface IZoo
}
}
class Experiment {
annotation class Type
@Type
data class Group(s: String)
}
class Foo {
open class Bar {
object Zoo
}
}
class `A$B` {
class C
@JvmField lateinit var c: C
@JvmField lateinit var de: `D$E`
@JvmField lateinit var jc: `J$B`.C
@JvmField lateinit var jde: `J$B`.`D$E`
class `D$E` {
class F
class `F$G`
@JvmField lateinit var f: F
@JvmField lateinit var fg: `F$G`
@JvmField lateinit var jf: `J$B`.`D$E`.F
@JvmField lateinit var jfg: `J$B`.`D$E`.`F$G`
}
class `D$$E`
class `D$$$E`
@JvmField lateinit var dee: `D$$E`
@JvmField lateinit var deee: `D$$$E`
@JvmField lateinit var jdee: `J$B`.`D$$E`
@JvmField lateinit var jdeee: `J$B`.`D$$$E`
}
@IFoo.IBar.Anno(IFoo.IBar.IZoo::class, Foo.Bar::class)
class Test1(val zoo: Foo.Bar.Zoo) : Foo.Bar(), IFoo.IBar, IFoo.IBar.IZoo {
fun a(): Thread.State = Thread.State.NEW
fun b(foo: JavaClass.Foo, bar: JavaClass.Foo.Bar) {}
}
@@ -0,0 +1,198 @@
package test;
@kotlin.Metadata()
public final class A$B {
@org.jetbrains.annotations.NotNull()
public test.A$B.C c;
@org.jetbrains.annotations.NotNull()
public test.A$B.D$E de;
@org.jetbrains.annotations.NotNull()
public test.J$B.C jc;
@org.jetbrains.annotations.NotNull()
public test.J$B.D$E jde;
@org.jetbrains.annotations.NotNull()
public test.A$B.D$$E dee;
@org.jetbrains.annotations.NotNull()
public test.A$B.D$$$E deee;
@org.jetbrains.annotations.NotNull()
public test.J$B.D$$E jdee;
@org.jetbrains.annotations.NotNull()
public test.J$B.D$$$E jdeee;
public A$B() {
super();
}
@kotlin.Metadata()
public static final class C {
public C() {
super();
}
}
@kotlin.Metadata()
public static final class D$E {
@org.jetbrains.annotations.NotNull()
public test.A$B.D$E.F f;
@org.jetbrains.annotations.NotNull()
public test.A$B.D$E.F$G fg;
@org.jetbrains.annotations.NotNull()
public test.J$B.D$E.F jf;
@org.jetbrains.annotations.NotNull()
public test.J$B.D$E.F$G jfg;
public D$E() {
super();
}
@kotlin.Metadata()
public static final class F {
public F() {
super();
}
}
@kotlin.Metadata()
public static final class F$G {
public F$G() {
super();
}
}
}
@kotlin.Metadata()
public static final class D$$E {
public D$$E() {
super();
}
}
@kotlin.Metadata()
public static final class D$$$E {
public D$$$E() {
super();
}
}
}
////////////////////
package test;
@kotlin.Metadata()
public final class Experiment {
public Experiment() {
super();
}
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public static abstract @interface Type {
}
@kotlin.Metadata()
@test.Experiment.Type()
public static final class Group {
public Group(@org.jetbrains.annotations.NotNull()
java.lang.String s) {
super();
}
@org.jetbrains.annotations.NotNull()
public final test.Experiment.Group copy(@org.jetbrains.annotations.NotNull()
java.lang.String s) {
return null;
}
}
}
////////////////////
package test;
@kotlin.Metadata()
public final class Foo {
public Foo() {
super();
}
@kotlin.Metadata()
public static class Bar {
public Bar() {
super();
}
@kotlin.Metadata()
public static final class Zoo {
public static final test.Foo.Bar.Zoo INSTANCE = null;
private Zoo() {
super();
}
}
}
}
////////////////////
package test;
@kotlin.Metadata()
public abstract interface IFoo {
@kotlin.Metadata()
public static abstract interface IBar {
@kotlin.Metadata()
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
public static abstract @interface Anno {
public abstract java.lang.Class<?>[] value();
}
@kotlin.Metadata()
@test.IFoo.IBar.Anno(value = {test.IFoo.IBar.IZoo.class})
public static abstract interface IZoo {
}
}
}
////////////////////
package test;
@kotlin.Metadata()
@test.IFoo.IBar.Anno(value = {test.IFoo.IBar.IZoo.class, test.Foo.Bar.class})
public final class Test1 extends test.Foo.Bar implements test.IFoo.IBar, test.IFoo.IBar.IZoo {
@org.jetbrains.annotations.NotNull()
private final test.Foo.Bar.Zoo zoo = null;
@org.jetbrains.annotations.NotNull()
public final java.lang.Thread.State a() {
return null;
}
public final void b(@org.jetbrains.annotations.NotNull()
test.JavaClass.Foo foo, @org.jetbrains.annotations.NotNull()
test.JavaClass.Foo.Bar bar) {
}
@org.jetbrains.annotations.NotNull()
public final test.Foo.Bar.Zoo getZoo() {
return null;
}
public Test1(@org.jetbrains.annotations.NotNull()
test.Foo.Bar.Zoo zoo) {
super();
}
}